Skip to content

Commit

Permalink
src/config.ts: initialize the Configuration singleton during activation
Browse files Browse the repository at this point in the history
Prompt the user if the workspace isn't trusted but workspace config is found.

And register 'go.workspace.isTrusted.toggle' (Go: Toggle Workspace Trust Flag)
command.

Change-Id: Iaaa2990a98b60bbbf1d59d5c18e5043e1386d44f
Reviewed-on: https://go-review.googlesource.com/c/vscode-go/+/283254
Trust: Hyang-Ah Hana Kim <[email protected]>
Run-TryBot: Hyang-Ah Hana Kim <[email protected]>
Reviewed-by: Suzy Mueller <[email protected]>
TryBot-Result: kokoro <[email protected]>
  • Loading branch information
hyangah committed Jan 15, 2021
1 parent d62869d commit 3a013bd
Show file tree
Hide file tree
Showing 5 changed files with 76 additions and 5 deletions.
4 changes: 4 additions & 0 deletions docs/commands.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,3 +206,7 @@ Show the current Go survey configuration
### `Go: Reset Survey Configuration`

Reset the current Go survey configuration history

### `Go: Toggle Workspace Trust Flag`

Toggle the workspace trust flag. Workspace settings that determine tool locations are disabled by default in untrusted workspaces.
4 changes: 4 additions & 0 deletions docs/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ To view the list of settings:
3. Click on the `Feature Contributions` tab.
4. Scroll through the list under `Settings`.

## Security

This extension runs a few [third-party command-line tools](tools.md) found from the locations determined by the `PATH` or `Path` environment variable, and the settings such as `"go.alternateTools"` or `"go.toolsGopath"`. Configuring them in workspace settings allows users to conveniently select a different set of tools based on project's need, but also allows attackers to run arbitrary binaries on your machine if they successfuly convince you to open a random repository. In order to reduce the security risk, the extension reads those settings from user settings by default. If the repository can be trusted and workspace settings must be used, you can mark the workspace as a trusted workspace using the `"Go: Toggle Workspace Trust Flag"` command.

## Detailed list

<!-- Everything below this line is generated. DO NOT EDIT. -->
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -400,6 +400,11 @@
"command": "go.survey.resetConfig",
"title": "Go: Reset Survey Configuration",
"description": "Reset the current Go survey configuration history"
},
{
"command": "go.workspace.isTrusted.toggle",
"title": "Go: Toggle Workspace Trust Flag",
"description": "Toggle the workspace trust flag. Workspace settings that determine tool locations are disabled by default in untrusted workspaces."
}
],
"breakpoints": [
Expand Down
58 changes: 56 additions & 2 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,76 @@
*--------------------------------------------------------*/

import vscode = require('vscode');
import { getFromWorkspaceState, updateWorkspaceState } from './stateUtils';

const WORKSPACE_IS_TRUSTED_KEY = 'WORKSPACE_IS_TRUSTED_KEY';
const SECURITY_SENSITIVE_CONFIG: string[] = [
'goroot', 'gopath', 'toolsGopath', 'alternateTools'
];

let defaultConfig: Configuration = null;

// Initialize the singleton defaultConfig and register related commands.
// Prompt if workspace configuration was found but had to be ignored until
// the user has to explicitly opt in to trust the workspace.
export async function initConfig(ctx: vscode.ExtensionContext) {
const isTrusted = getFromWorkspaceState(WORKSPACE_IS_TRUSTED_KEY, false);
defaultConfig = new Configuration(isTrusted, vscode.workspace.getConfiguration);
ctx.subscriptions.push(
vscode.commands.registerCommand('go.workspace.isTrusted.toggle', defaultConfig.toggleWorkspaceIsTrusted)
);

if (isTrusted) {
return;
}
const ignored = ignoredWorkspaceConfig(vscode.workspace.getConfiguration('go'), SECURITY_SENSITIVE_CONFIG);
if (ignored.length === 0) {
return;
}
const ignoredSettings = ignored.map((x) => `"go.${x}"`).join(',');
const val = await vscode.window.showWarningMessage(
`Some workspace/folder-level settings (${ignoredSettings}) from the untrusted workspace are disabled ` +
`by default. If this workspace is trusted, explicitly enable the workspace/folder-level settings ` +
`by running the "Go: Toggle Workspace Trust Flag" command.`,
'OK',
'Trust This Workspace',
'More Info');
switch (val) {
case 'Trust This Workspace':
await defaultConfig.toggleWorkspaceIsTrusted();
break;
case 'More Info':
vscode.env.openExternal(
vscode.Uri.parse(`https://github.com/golang/vscode-go/blob/master/docs/settings.md#security`));
break;
default:
break;
}
}

function ignoredWorkspaceConfig(cfg: vscode.WorkspaceConfiguration, keys: string[]) {
return keys.filter((key) => {
const inspect = cfg.inspect(key);
return inspect.workspaceValue !== undefined || inspect.workspaceFolderValue !== undefined;
});
}

// Go extension configuration for a workspace.
export class Configuration {
constructor(
private isTrustedWorkspace: boolean,
private workspaceIsTrusted: boolean,
private getConfiguration: typeof vscode.workspace.getConfiguration) { }

public async toggleWorkspaceIsTrusted() {
this.workspaceIsTrusted = !this.workspaceIsTrusted;
await updateWorkspaceState(WORKSPACE_IS_TRUSTED_KEY, this.workspaceIsTrusted);
}

// returns a Proxied vscode.WorkspaceConfiguration, which prevents
// from using the workspace configuration if the workspace is untrusted.
public get<T>(uri?: vscode.Uri): vscode.WorkspaceConfiguration {
const cfg = this.getConfiguration('go', uri);
if (this.isTrustedWorkspace) {
if (this.workspaceIsTrusted) {
return cfg;
}

Expand Down
10 changes: 7 additions & 3 deletions src/goMain.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import * as path from 'path';
import semver = require('semver');
import vscode = require('vscode');
import { initConfig } from './config';
import { extensionId } from './const';
import { browsePackages } from './goBrowsePackage';
import { buildCode } from './goBuild';
Expand Down Expand Up @@ -83,17 +84,20 @@ export let vetDiagnosticCollection: vscode.DiagnosticCollection;
// the configuration of the server.
export let restartLanguageServer = () => { return; };

export function activate(ctx: vscode.ExtensionContext) {
export async function activate(ctx: vscode.ExtensionContext) {
if (process.env['VSCODE_GO_IN_TEST'] === '1') { // Make sure this does not run when running in test.
return;
}
const cfg = getGoConfig();
setLogConfig(cfg['logging']);

setGlobalState(ctx.globalState);
setWorkspaceState(ctx.workspaceState);
setEnvironmentVariableCollection(ctx.environmentVariableCollection);

await initConfig(ctx);

const cfg = getGoConfig();
setLogConfig(cfg['logging']);

if (vscode.window.registerWebviewPanelSerializer) {
// Make sure we register a serializer in activation event
vscode.window.registerWebviewPanelSerializer(WelcomePanel.viewType, {
Expand Down

0 comments on commit 3a013bd

Please sign in to comment.