Skip to content

Commit

Permalink
Encourage use of asWebviewUri instead of vscode-resource directly
Browse files Browse the repository at this point in the history
  • Loading branch information
mjbvz committed Sep 13, 2019
1 parent 0fc8415 commit 0fe4259
Showing 1 changed file with 19 additions and 13 deletions.
32 changes: 19 additions & 13 deletions api/extension-guides/webview.md
Expand Up @@ -412,11 +412,9 @@ In addition, the **Developer: Reload Webview** command reloads all active webvie

## Loading local content

Webviews run in isolated contexts that cannot directly access local resources. This is done for security reasons. This means that in order to load images, stylesheets, and other resources from your extension, or to load any content from the user's current workspace, you must use the `vscode-resource:` scheme inside the webview.
Webviews run in isolated contexts that cannot directly access local resources. This is done for security reasons. This means that in order to load images, stylesheets, and other resources from your extension, or to load any content from the user's current workspace, you must use the `Webview.asWebviewUri` function to convert a local `file:` URI into a special URI that VS Code can use to load a subset of local resources.

The `vscode-resource:` scheme is similar to the `file:` scheme, but it only allows access to select local files. Like with `file:`, `vscode-resource:` loads a resource at a given absolute path from the disk.

Imagine that we want to start bundling the cat gifs into our extension rather pulling them from Giphy. To do this, we first create a URI to the file on disk and then update this URI to use the `vscode-resource` scheme:
Imagine that we want to start bundling the cat gifs into our extension rather pulling them from Giphy. To do this, we first create a URI to the file on disk and then pass these URIs through the `asWebviewUri` function:

```ts
import * as vscode from 'vscode';
Expand All @@ -438,30 +436,34 @@ export function activate(context: vscode.ExtensionContext) {
);

// And get the special URI to use with the webview
const catGifSrc = onDiskPath.with({ scheme: 'vscode-resource' });
const catGifSrc = panel.webview.asWebviewUri(onDiskPath);

panel.webview.html = getWebviewContent(catGifSrc);
})
);
}
```

The value for `catGifSrc` will be something like:
If we debug this code, we'd see that the actual value for `catGifSrc` is something like:

```bash
```
vscode-resource:/Users/toonces/projects/vscode-cat-coding/media/cat.gif
```

By default, `vscode-resource:` can only access resources in the following locations:
VS Code understands this special URI and will used it to load our gif from the disk!

By default, webviews can only access resources in the following locations:

- Within your extension's install directory.
- Within the user's currently active workspace.

Use the `WebviewOptions.localResourceRoots` to allow access to additional local resources.

You can also always use data URIs to embed resources directly within the webview.

### Controlling access to local resources

Webviews can control which resources `vscode-resource:` can load using the `localResourceRoots` option. `localResourceRoots` defines a set of root URIs from which local content may be loaded.
Webviews can control which resources can be loaded from the user's machine with `localResourceRoots` option. `localResourceRoots` defines a set of root URIs from which local content may be loaded.

We can use `localResourceRoots` to restrict **Cat Coding** webviews to only load resources from a `media` directory in our extension:

Expand All @@ -478,14 +480,16 @@ export function activate(context: vscode.ExtensionContext) {
vscode.ViewColumn.One,
{
// Only allow the webview to access resources in our extension's media directory
localResourceRoots: [vscode.Uri.file(path.join(context.extensionPath, 'media'))]
localResourceRoots: [
vscode.Uri.file(path.join(context.extensionPath, 'media'))
]
}
);

const onDiskPath = vscode.Uri.file(
path.join(context.extensionPath, 'media', 'cat.gif')
);
const catGifSrc = onDiskPath.with({ scheme: 'vscode-resource' });
const catGifSrc = panel.webview.asWebviewUri(onDiskPath);

panel.webview.html = getWebviewContent(catGifSrc);
})
Expand All @@ -495,7 +499,7 @@ export function activate(context: vscode.ExtensionContext) {

To disallow all local resources, just set `localResourceRoots` to `[]`.

In general, webviews should be as restrictive as possible in loading local resources. However, keep in mind that `vscode-resource` and `localResourceRoots` do not offer complete security protection on their own. Make sure your webview also follows [security best practices](#security), and strongly consider adding a [content security policy](#content-security-policy) to further restrict the content that can be loaded.
In general, webviews should be as restrictive as possible in loading local resources. However, keep in mind that `localResourceRoots` does not offer complete security protection on its own. Make sure your webview also follows [security best practices](#security), and add a [content security policy](#content-security-policy) to further restrict the content that can be loaded.

### Theming webview content

Expand Down Expand Up @@ -804,10 +808,12 @@ The policy `default-src 'none';` disallows all content. We can then turn back on
```html
<meta
http-equiv="Content-Security-Policy"
content="default-src 'none'; img-src vscode-resource: https:; script-src vscode-resource:; style-src vscode-resource:;"
content="default-src 'none'; img-src ${webview.cspSource} https:; script-src ${webview.cspSource}; style-src ${webview.cspSource};"
/>
```

The `${webview.cspSource}` value is a placeholder for a value that comes from the webview object itself. See the [webview sample](https://github.com/Microsoft/vscode-extension-samples/blob/master/webview-sample) for a complete example of how to use this value.

This content security policy also implicitly disables inline scripts and styles. It is a best practice to extract all inline styles and scripts to external files so that they can be properly loaded without relaxing the content security policy.

### Only load content over https
Expand Down

0 comments on commit 0fe4259

Please sign in to comment.