forwarding: add a warning for public ports (#192599)

* forwarding: add a warning for public ports

A number of users have raised some security concerns about port
forwarding. Forwarded ports are private (requiring auth with the same
GH account that did the forwarding) by default. When making a port
public, show the following dialog:

![](https://memes.peet.io/img/23-09-3f3351c7-cdcd-46e5-9d0f-123e4dda6b3c.png)

* Update extensions/tunnel-forwarding/src/extension.ts

Co-authored-by: Joyce Er <joyce.er@microsoft.com>

---------

Co-authored-by: Joyce Er <joyce.er@microsoft.com>
This commit is contained in:
Connor Peet
2023-09-08 10:19:50 -07:00
committed by GitHub
parent 8627ee4504
commit cd4bd7e64b

View File

@@ -67,7 +67,7 @@ export async function activate(context: vscode.ExtensionContext) {
}
const logger = new Logger(vscode.l10n.t('Port Forwarding'));
const provider = new TunnelProvider(logger);
const provider = new TunnelProvider(logger, context);
context.subscriptions.push(
vscode.commands.registerCommand('tunnel-forwarding.showLog', () => logger.show()),
@@ -120,6 +120,8 @@ class Logger {
}
}
const didWarnPublicKey = 'didWarnPublic';
class TunnelProvider implements vscode.TunnelProvider {
private readonly tunnels = new Set<Tunnel>();
private readonly stateChange = new vscode.EventEmitter<StateT>();
@@ -136,10 +138,16 @@ class TunnelProvider implements vscode.TunnelProvider {
public readonly onDidStateChange = this.stateChange.event;
constructor(private readonly logger: Logger) { }
constructor(private readonly logger: Logger, private readonly context: vscode.ExtensionContext) { }
/** @inheritdoc */
public async provideTunnel(tunnelOptions: vscode.TunnelOptions): Promise<vscode.Tunnel> {
public async provideTunnel(tunnelOptions: vscode.TunnelOptions): Promise<vscode.Tunnel | undefined> {
if (tunnelOptions.privacy === TunnelPrivacyId.Public) {
if (!(await this.consentPublicPort(tunnelOptions.remoteAddress.port))) {
return;
}
}
const tunnel = new Tunnel(
tunnelOptions.remoteAddress,
(tunnelOptions.privacy as TunnelPrivacyId) || TunnelPrivacyId.Private,
@@ -184,6 +192,31 @@ class TunnelProvider implements vscode.TunnelProvider {
this.updateActivePortsIfRunning();
}
private async consentPublicPort(portNumber: number) {
const didWarn = this.context.globalState.get(didWarnPublicKey, false);
if (didWarn) {
return true;
}
const continueOpt = vscode.l10n.t('Continue');
const dontShowAgain = vscode.l10n.t("Don't show again");
const r = await vscode.window.showWarningMessage(
vscode.l10n.t("You're about to create a publicly forwarded port. Anyone on the internet will be able to connect to the service listening on port {0}. You should only proceed if this service is secure and non-sensitive.", portNumber),
{ modal: true },
continueOpt,
dontShowAgain,
);
if (r === continueOpt) {
// continue
} else if (r === dontShowAgain) {
await this.context.globalState.update(didWarnPublicKey, true);
} else {
return false;
}
return true;
}
private isInStateWithProcess(process: ChildProcessWithoutNullStreams) {
return (
(this.state.state === State.Starting || this.state.state === State.Active) &&