T09 · Insecure Skill Coding Practices
- Location
scripts/flow-webapi/utils/paths.ts:34- Finding
Shell Command Injection Through WSL Profile Path Conversion
- Content
View full analysis
Vulnerability Details
File Location:
scripts/flow-webapi/utils/paths.ts:34-37, with environment-variable sources atscripts/flow-webapi/utils/paths.ts:47-51
Vulnerability Type: OS command injection
Risk Level: HighVulnerable Code
ts function toWslPath(rawWindowsPath: string): string | null { try { return execSync(`wslpath -u "${rawWindowsPath}"`, { encoding: 'utf-8', timeout: 5000 }).trim() || null; } catch { return null; } }The value passed to this function originates from environment variables:
ts const winOverride = process.env.AGENT_BROWSER_USER_DATA_DIR_WIN?.trim() || process.env.FLOW_WEB_CHROME_USER_DATA_DIR_WIN?.trim(); if (winOverride) { const converted = toWslPath(winOverride); if (converted) return converted; }Technical Analysis
rawWindowsPathis inserted directly into a command string executed byexecSync. BecauseexecSyncinvokes a shell for string commands, embedded quotation marks and shell metacharacters can terminate the intended argument and introduce an additional command.The input is obtained from
AGENT_BROWSER_USER_DATA_DIR_WINorFLOW_WEB_CHROME_USER_DATA_DIR_WIN. No validation, escaping, or argument separation is performed. An attacker who can influence the Skill's environment can therefore convert a profile-path configuration value into arbitrary command execution.Attack Path
- An attacker or untrusted execution environment sets
AGENT_BROWSER_USER_DATA_DIR_WINorFLOW_WEB_CHROME_USER_DATA_DIR_WINto a value containing a closing quotation mark and shell syntax. - The Skill runs under WSL and calls
resolveFlowWebChromeProfileDir(). - The environment value is passed to
toWslPath(). execSyncparses the injected syntax as part of the shell command.- The injected command executes with the privileges of the user running the Skill.
Impact Assessment
Successful exploitation pr ...[truncated 317 chars]
- An attacker or untrusted execution environment sets
- Remediation
View remediation
Remediation Suggestions
Do not pass environment-derived data through a shell command string. Invoke
wslpathwith an argument array:ts import { execFileSync } from 'node:child_process'; function toWslPath(rawWindowsPath: string): string | null { try { return execFileSync('wslpath', ['-u', rawWindowsPath], { encoding: 'utf8', timeout: 5000, }).trim() || null; } catch { return null; } }Additionally:
- Reject null bytes, control characters, and newline characters.
- Validate that the input conforms to an expected Windows path format.
- Treat environment configuration as untrusted input.
- Avoid shell execution wherever a direct process API can be used.
