Skip to content

Commit 3a013bd

Browse files
committed
src/config.ts: initialize the Configuration singleton during activation
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]>
1 parent d62869d commit 3a013bd

File tree

5 files changed

+76
-5
lines changed

5 files changed

+76
-5
lines changed

docs/commands.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,3 +206,7 @@ Show the current Go survey configuration
206206
### `Go: Reset Survey Configuration`
207207

208208
Reset the current Go survey configuration history
209+
210+
### `Go: Toggle Workspace Trust Flag`
211+
212+
Toggle the workspace trust flag. Workspace settings that determine tool locations are disabled by default in untrusted workspaces.

docs/settings.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ To view the list of settings:
1717
3. Click on the `Feature Contributions` tab.
1818
4. Scroll through the list under `Settings`.
1919

20+
## Security
21+
22+
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.
23+
2024
## Detailed list
2125

2226
<!-- Everything below this line is generated. DO NOT EDIT. -->

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,11 @@
400400
"command": "go.survey.resetConfig",
401401
"title": "Go: Reset Survey Configuration",
402402
"description": "Reset the current Go survey configuration history"
403+
},
404+
{
405+
"command": "go.workspace.isTrusted.toggle",
406+
"title": "Go: Toggle Workspace Trust Flag",
407+
"description": "Toggle the workspace trust flag. Workspace settings that determine tool locations are disabled by default in untrusted workspaces."
403408
}
404409
],
405410
"breakpoints": [

src/config.ts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,76 @@
44
*--------------------------------------------------------*/
55

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

9+
const WORKSPACE_IS_TRUSTED_KEY = 'WORKSPACE_IS_TRUSTED_KEY';
810
const SECURITY_SENSITIVE_CONFIG: string[] = [
911
'goroot', 'gopath', 'toolsGopath', 'alternateTools'
1012
];
1113

14+
let defaultConfig: Configuration = null;
15+
16+
// Initialize the singleton defaultConfig and register related commands.
17+
// Prompt if workspace configuration was found but had to be ignored until
18+
// the user has to explicitly opt in to trust the workspace.
19+
export async function initConfig(ctx: vscode.ExtensionContext) {
20+
const isTrusted = getFromWorkspaceState(WORKSPACE_IS_TRUSTED_KEY, false);
21+
defaultConfig = new Configuration(isTrusted, vscode.workspace.getConfiguration);
22+
ctx.subscriptions.push(
23+
vscode.commands.registerCommand('go.workspace.isTrusted.toggle', defaultConfig.toggleWorkspaceIsTrusted)
24+
);
25+
26+
if (isTrusted) {
27+
return;
28+
}
29+
const ignored = ignoredWorkspaceConfig(vscode.workspace.getConfiguration('go'), SECURITY_SENSITIVE_CONFIG);
30+
if (ignored.length === 0) {
31+
return;
32+
}
33+
const ignoredSettings = ignored.map((x) => `"go.${x}"`).join(',');
34+
const val = await vscode.window.showWarningMessage(
35+
`Some workspace/folder-level settings (${ignoredSettings}) from the untrusted workspace are disabled ` +
36+
`by default. If this workspace is trusted, explicitly enable the workspace/folder-level settings ` +
37+
`by running the "Go: Toggle Workspace Trust Flag" command.`,
38+
'OK',
39+
'Trust This Workspace',
40+
'More Info');
41+
switch (val) {
42+
case 'Trust This Workspace':
43+
await defaultConfig.toggleWorkspaceIsTrusted();
44+
break;
45+
case 'More Info':
46+
vscode.env.openExternal(
47+
vscode.Uri.parse(`https://github.com/golang/vscode-go/blob/master/docs/settings.md#security`));
48+
break;
49+
default:
50+
break;
51+
}
52+
}
53+
54+
function ignoredWorkspaceConfig(cfg: vscode.WorkspaceConfiguration, keys: string[]) {
55+
return keys.filter((key) => {
56+
const inspect = cfg.inspect(key);
57+
return inspect.workspaceValue !== undefined || inspect.workspaceFolderValue !== undefined;
58+
});
59+
}
60+
1261
// Go extension configuration for a workspace.
1362
export class Configuration {
1463
constructor(
15-
private isTrustedWorkspace: boolean,
64+
private workspaceIsTrusted: boolean,
1665
private getConfiguration: typeof vscode.workspace.getConfiguration) { }
1766

67+
public async toggleWorkspaceIsTrusted() {
68+
this.workspaceIsTrusted = !this.workspaceIsTrusted;
69+
await updateWorkspaceState(WORKSPACE_IS_TRUSTED_KEY, this.workspaceIsTrusted);
70+
}
71+
1872
// returns a Proxied vscode.WorkspaceConfiguration, which prevents
1973
// from using the workspace configuration if the workspace is untrusted.
2074
public get<T>(uri?: vscode.Uri): vscode.WorkspaceConfiguration {
2175
const cfg = this.getConfiguration('go', uri);
22-
if (this.isTrustedWorkspace) {
76+
if (this.workspaceIsTrusted) {
2377
return cfg;
2478
}
2579

src/goMain.ts

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import * as path from 'path';
1010
import semver = require('semver');
1111
import vscode = require('vscode');
12+
import { initConfig } from './config';
1213
import { extensionId } from './const';
1314
import { browsePackages } from './goBrowsePackage';
1415
import { buildCode } from './goBuild';
@@ -83,17 +84,20 @@ export let vetDiagnosticCollection: vscode.DiagnosticCollection;
8384
// the configuration of the server.
8485
export let restartLanguageServer = () => { return; };
8586

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

9392
setGlobalState(ctx.globalState);
9493
setWorkspaceState(ctx.workspaceState);
9594
setEnvironmentVariableCollection(ctx.environmentVariableCollection);
9695

96+
await initConfig(ctx);
97+
98+
const cfg = getGoConfig();
99+
setLogConfig(cfg['logging']);
100+
97101
if (vscode.window.registerWebviewPanelSerializer) {
98102
// Make sure we register a serializer in activation event
99103
vscode.window.registerWebviewPanelSerializer(WelcomePanel.viewType, {

0 commit comments

Comments
 (0)