mirror of
https://github.com/Microsoft/vscode
synced 2024-08-28 13:29:44 +00:00
Introduce trustedExtensionProtocolHandlers (#194304)
* remove url * use trustedExtensionProtocolHandlers
This commit is contained in:
parent
3ff4f98cdd
commit
45358184ef
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.83.0",
|
||||
"distro": "7181d0c2e9094f4f9f90764e81ebac2443072cb7",
|
||||
"distro": "e61050c5d43d2c66a196fafaa2b78d4f2a8c929a",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
|
@ -231,4 +231,4 @@
|
|||
"optionalDependencies": {
|
||||
"windows-foreground-love": "0.5.0"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -114,6 +114,7 @@ export interface IProductConfiguration {
|
|||
readonly languageExtensionTips?: readonly string[];
|
||||
readonly trustedExtensionUrlPublicKeys?: IStringDictionary<string[]>;
|
||||
readonly trustedExtensionAuthAccess?: readonly string[];
|
||||
readonly trustedExtensionProtocolHandlers?: readonly string[];
|
||||
|
||||
readonly commandPaletteSuggestedCommandIds?: string[];
|
||||
|
||||
|
|
|
@ -41,8 +41,6 @@ import { NativeParsedArgs } from 'vs/platform/environment/common/argv';
|
|||
import { IEnvironmentMainService } from 'vs/platform/environment/electron-main/environmentMainService';
|
||||
import { isLaunchedFromCli } from 'vs/platform/environment/node/argvHelper';
|
||||
import { getResolvedShellEnv } from 'vs/platform/shell/node/shellEnv';
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { ExtensionUrlTrustService } from 'vs/platform/extensionManagement/node/extensionUrlTrustService';
|
||||
import { IExtensionHostStarter, ipcExtensionHostStarterChannelName } from 'vs/platform/extensions/common/extensionHostStarter';
|
||||
import { ExtensionHostStarter } from 'vs/platform/extensions/electron-main/extensionHostStarter';
|
||||
import { IExternalTerminalMainService } from 'vs/platform/externalTerminal/electron-main/externalTerminal';
|
||||
|
@ -968,9 +966,6 @@ export class CodeApplication extends Disposable {
|
|||
// Menubar
|
||||
services.set(IMenubarMainService, new SyncDescriptor(MenubarMainService));
|
||||
|
||||
// Extension URL Trust
|
||||
services.set(IExtensionUrlTrustService, new SyncDescriptor(ExtensionUrlTrustService));
|
||||
|
||||
// Extension Host Starter
|
||||
services.set(IExtensionHostStarter, new SyncDescriptor(ExtensionHostStarter));
|
||||
|
||||
|
@ -1118,10 +1113,6 @@ export class CodeApplication extends Disposable {
|
|||
const urlChannel = ProxyChannel.fromService(accessor.get(IURLService), disposables);
|
||||
mainProcessElectronServer.registerChannel('url', urlChannel);
|
||||
|
||||
// Extension URL Trust
|
||||
const extensionUrlTrustChannel = ProxyChannel.fromService(accessor.get(IExtensionUrlTrustService), disposables);
|
||||
mainProcessElectronServer.registerChannel('extensionUrlTrust', extensionUrlTrustChannel);
|
||||
|
||||
// Webview Manager
|
||||
const webviewChannel = ProxyChannel.fromService(accessor.get(IWebviewManagerService), disposables);
|
||||
mainProcessElectronServer.registerChannel('webview', webviewChannel);
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export const IExtensionUrlTrustService = createDecorator<IExtensionUrlTrustService>('extensionUrlTrustService');
|
||||
|
||||
export interface IExtensionUrlTrustService {
|
||||
readonly _serviceBrand: undefined;
|
||||
isExtensionUrlTrusted(extensionId: string, url: string): Promise<boolean>;
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as crypto from 'crypto';
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
export class ExtensionUrlTrustService implements IExtensionUrlTrustService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
private trustedExtensionUrlPublicKeys = new Map<string, (crypto.KeyObject | string | null)[]>();
|
||||
|
||||
constructor(
|
||||
@IProductService private readonly productService: IProductService,
|
||||
@ILogService private readonly logService: ILogService
|
||||
) { }
|
||||
|
||||
async isExtensionUrlTrusted(extensionId: string, url: string): Promise<boolean> {
|
||||
if (!this.productService.trustedExtensionUrlPublicKeys) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'There are no configured trusted keys');
|
||||
return false;
|
||||
}
|
||||
|
||||
const match = /^(.*)#([^#]+)$/.exec(url);
|
||||
|
||||
if (!match) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Uri has no fragment', url);
|
||||
return false;
|
||||
}
|
||||
|
||||
const [, originalUrl, fragment] = match;
|
||||
|
||||
let keys = this.trustedExtensionUrlPublicKeys.get(extensionId);
|
||||
|
||||
if (!keys) {
|
||||
keys = this.productService.trustedExtensionUrlPublicKeys[extensionId];
|
||||
|
||||
if (!keys || keys.length === 0) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Extension doesn\'t have any trusted keys', extensionId);
|
||||
return false;
|
||||
}
|
||||
|
||||
this.trustedExtensionUrlPublicKeys.set(extensionId, [...keys]);
|
||||
}
|
||||
|
||||
const fragmentBuffer = Buffer.from(decodeURIComponent(fragment), 'base64');
|
||||
|
||||
if (fragmentBuffer.length <= 6) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Uri fragment is not a signature', url);
|
||||
return false;
|
||||
}
|
||||
|
||||
const timestampBuffer = fragmentBuffer.slice(0, 6);
|
||||
const timestamp = fragmentBuffer.readUIntBE(0, 6);
|
||||
const diff = Date.now() - timestamp;
|
||||
|
||||
if (diff < 0 || diff > 3_600_000) { // 1 hour
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Signed uri has expired', url);
|
||||
return false;
|
||||
}
|
||||
|
||||
const signatureBuffer = fragmentBuffer.slice(6);
|
||||
const verify = crypto.createVerify('SHA256');
|
||||
verify.write(timestampBuffer);
|
||||
verify.write(Buffer.from(originalUrl));
|
||||
verify.end();
|
||||
|
||||
for (let i = 0; i < keys.length; i++) {
|
||||
let key = keys[i];
|
||||
|
||||
if (key === null) { // failed to be parsed before
|
||||
continue;
|
||||
} else if (typeof key === 'string') { // needs to be parsed
|
||||
try {
|
||||
key = crypto.createPublicKey({ key: Buffer.from(key, 'base64'), format: 'der', type: 'spki' });
|
||||
keys[i] = key;
|
||||
} catch (err) {
|
||||
this.logService.warn('ExtensionUrlTrustService#isExtensionUrlTrusted', `Failed to parse trusted extension uri public key #${i + 1} for ${extensionId}:`, err);
|
||||
keys[i] = null;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (verify.verify(key, signatureBuffer)) {
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Signed uri is valid', url);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
this.logService.trace('ExtensionUrlTrustService#isExtensionUrlTrusted', 'Signed uri could not be verified', url);
|
||||
return false;
|
||||
}
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { InstantiationType, registerSingleton } from 'vs/platform/instantiation/common/extensions';
|
||||
|
||||
class ExtensionUrlTrustService implements IExtensionUrlTrustService {
|
||||
|
||||
declare readonly _serviceBrand: undefined;
|
||||
|
||||
async isExtensionUrlTrusted(): Promise<boolean> {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IExtensionUrlTrustService, ExtensionUrlTrustService, InstantiationType.Delayed);
|
|
@ -1,9 +0,0 @@
|
|||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { registerMainProcessRemoteService } from 'vs/platform/ipc/electron-sandbox/services';
|
||||
|
||||
registerMainProcessRemoteService(IExtensionUrlTrustService, 'extensionUrlTrust');
|
|
@ -26,10 +26,10 @@ import { Action2, MenuId, registerAction2 } from 'vs/platform/actions/common/act
|
|||
import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/common/quickInput';
|
||||
import { IProgressService, ProgressLocation } from 'vs/platform/progress/common/progress';
|
||||
import { IsWebContext } from 'vs/platform/contextkey/common/contextkeys';
|
||||
import { IExtensionUrlTrustService } from 'vs/platform/extensionManagement/common/extensionUrlTrust';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
|
||||
const FIVE_MINUTES = 5 * 60 * 1000;
|
||||
const THIRTY_SECONDS = 30 * 1000;
|
||||
|
@ -121,7 +121,7 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
|
|||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IProgressService private readonly progressService: IProgressService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IExtensionUrlTrustService private readonly extensionUrlTrustService: IExtensionUrlTrustService
|
||||
@IProductService private readonly productService: IProductService
|
||||
) {
|
||||
this.userTrustedExtensionsStorage = new UserTrustedExtensionIdStorage(storageService);
|
||||
|
||||
|
@ -166,7 +166,7 @@ class ExtensionUrlHandler implements IExtensionUrlHandler, IURLHandler {
|
|||
}
|
||||
|
||||
const trusted = options?.trusted
|
||||
|| (options?.originalUrl ? await this.extensionUrlTrustService.isExtensionUrlTrusted(extensionId, options.originalUrl) : false)
|
||||
|| this.productService.trustedExtensionProtocolHandlers?.includes(extensionId)
|
||||
|| this.didUserTrustExtension(ExtensionIdentifier.toKey(extensionId));
|
||||
|
||||
if (!trusted) {
|
||||
|
|
|
@ -55,7 +55,6 @@ import 'vs/workbench/services/keybinding/electron-sandbox/nativeKeyboardLayout';
|
|||
import 'vs/workbench/services/path/electron-sandbox/pathService';
|
||||
import 'vs/workbench/services/themes/electron-sandbox/nativeHostColorSchemeService';
|
||||
import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionManagementService';
|
||||
import 'vs/workbench/services/extensionManagement/electron-sandbox/extensionUrlTrustService';
|
||||
import 'vs/workbench/services/encryption/electron-sandbox/encryptionService';
|
||||
import 'vs/workbench/services/secrets/electron-sandbox/secretStorageService';
|
||||
import 'vs/workbench/services/localization/electron-sandbox/languagePackService';
|
||||
|
|
|
@ -41,7 +41,6 @@ import 'vs/workbench/services/keybinding/browser/keyboardLayoutService';
|
|||
import 'vs/workbench/services/extensions/browser/extensionService';
|
||||
import 'vs/workbench/services/extensionManagement/browser/webExtensionsScannerService';
|
||||
import 'vs/workbench/services/extensionManagement/common/extensionManagementServerService';
|
||||
import 'vs/workbench/services/extensionManagement/browser/extensionUrlTrustService';
|
||||
import 'vs/workbench/services/telemetry/browser/telemetryService';
|
||||
import 'vs/workbench/services/url/browser/urlService';
|
||||
import 'vs/workbench/services/update/browser/updateService';
|
||||
|
|
Loading…
Reference in a new issue