diff --git a/extensions/markdown-language-features/src/preview/documentRenderer.ts b/extensions/markdown-language-features/src/preview/documentRenderer.ts index 8a39c9cdf4d..c7bc75b9849 100644 --- a/extensions/markdown-language-features/src/preview/documentRenderer.ts +++ b/extensions/markdown-language-features/src/preview/documentRenderer.ts @@ -94,7 +94,7 @@ export class MdDocumentRenderer {
- ${csp} + `; + return `default-src 'none'; img-src 'self' ${rule} http: https: data:; media-src 'self' ${rule} http: https: data:; script-src 'nonce-${nonce}'; style-src 'self' ${rule} 'unsafe-inline' http: https: data:; font-src 'self' ${rule} http: https: data:;`; case MarkdownPreviewSecurityLevel.AllowInsecureLocalContent: - return ``; + return `default-src 'none'; img-src 'self' ${rule} https: data: http://localhost:* http://127.0.0.1:*; media-src 'self' ${rule} https: data: http://localhost:* http://127.0.0.1:*; script-src 'nonce-${nonce}'; style-src 'self' ${rule} 'unsafe-inline' https: data: http://localhost:* http://127.0.0.1:*; font-src 'self' ${rule} https: data: http://localhost:* http://127.0.0.1:*;`; case MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent: - return ''; + return ``; case MarkdownPreviewSecurityLevel.Strict: default: - return ``; + return `default-src 'none'; img-src 'self' ${rule} https: data:; media-src 'self' ${rule} https: data:; script-src 'nonce-${nonce}'; style-src 'self' ${rule} 'unsafe-inline' https: data:; font-src 'self' ${rule} https: data:;`; } } } diff --git a/extensions/markdown-language-features/src/preview/preview.ts b/extensions/markdown-language-features/src/preview/preview.ts index c19347f7b4b..b5f87d4c090 100644 --- a/extensions/markdown-language-features/src/preview/preview.ts +++ b/extensions/markdown-language-features/src/preview/preview.ts @@ -430,10 +430,14 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider { get cspSource() { return [ this._webviewPanel.webview.cspSource, - ...this._contributionProvider.contributions.previewResourceRoots.map(root => { - const dirRoot = root.path.endsWith('/') ? root : root.with({ path: root.path + '/' }); - return dirRoot.toString(); - }), + + // On web, we also need to allow loading of resources from contributed extensions + ...this._contributionProvider.contributions.previewResourceRoots + .filter(root => root.scheme === 'http' || root.scheme === 'https') + .map(root => { + const dirRoot = root.path.endsWith('/') ? root : root.with({ path: root.path + '/' }); + return dirRoot.toString(); + }), ].join(' '); }