Port - Restrict which sites out webview iframe can frame (#18495)

* protocol handler - normalize paths

* use `extUri` for normalizing paths

* :lipstick;

* Add content security policy to top level webview

This change hardens our webviews by adding a fairly restrictive csp to them. This CSP should only apply to the outer webview iframe, not to the inner iframe which is controlled by extensions

Co-authored-by: Benjamin Pasero <benjamin.pasero@microsoft.com>
Co-authored-by: Matt Bierner <matb@microsoft.com>
This commit is contained in:
Karl Burtram
2022-02-18 15:12:21 -08:00
committed by GitHub
parent eff847f35a
commit e0cb88599d
2 changed files with 24 additions and 12 deletions

View File

@@ -8,7 +8,7 @@ import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'
import { TernarySearchTree } from 'vs/base/common/map';
import { FileAccess, Schemas } from 'vs/base/common/network';
import { isLinux } from 'vs/base/common/platform';
import { extname } from 'vs/base/common/resources';
import { extname, normalizePath } from 'vs/base/common/resources';
import { URI } from 'vs/base/common/uri';
import { generateUuid } from 'vs/base/common/uuid';
import { INativeEnvironmentService } from 'vs/platform/environment/common/environment';
@@ -84,33 +84,43 @@ export class ProtocolMainService extends Disposable implements IProtocolMainServ
//#region vscode-file://
private handleResourceRequest(request: Electron.ProtocolRequest, callback: ProtocolCallback): void {
const uri = URI.parse(request.url);
// Restore the `vscode-file` URI to a `file` URI so that we can
// ensure the root is valid and properly tell Chrome where the
// resource is at.
const fileUri = FileAccess.asFileUri(uri);
const uri = this.requestToFileUri(request);
// first check by validRoots
if (this.validRoots.findSubstr(fileUri)) {
if (this.validRoots.findSubstr(uri)) {
return callback({
path: fileUri.fsPath
path: uri.fsPath
});
}
// then check by validExtensions
if (this.validExtensions.has(extname(fileUri))) {
if (this.validExtensions.has(extname(uri))) {
return callback({
path: fileUri.fsPath
path: uri.fsPath
});
}
// finally block to load the resource
this.logService.error(`${Schemas.vscodeFileResource}: Refused to load resource ${fileUri.fsPath} from ${Schemas.vscodeFileResource}: protocol (original URL: ${request.url})`);
this.logService.error(`${Schemas.vscodeFileResource}: Refused to load resource ${uri.fsPath} from ${Schemas.vscodeFileResource}: protocol (original URL: ${request.url})`);
return callback({ error: -3 /* ABORTED */ });
}
private requestToFileUri(request: Electron.ProtocolRequest): URI {
// 1.) Use `URI.parse()` util from us to convert the raw
// URL into our URI.
const requestUri = URI.parse(request.url);
// 2.) Use `FileAccess.asFileUri` to convert back from a
// `vscode-file:` URI to a `file:` URI.
const unnormalizedFileUri = FileAccess.asFileUri(requestUri);
// 3.) Strip anything from the URI that could result in
// relative paths (such as "..") by using `normalize`
return normalizePath(unnormalizedFileUri);
}
//#endregion
//#region IPC Object URLs