T09 · Insecure Skill Coding Practices
- Location
scripts/start_chrome.py:29- Finding
Environment-Controlled Shell Command Injection in Chrome Launcher
- Content
View full analysis
Vulnerability Details
File Location:
scripts/start_chrome.py, lines 29-39 and 67-79
Vulnerability Type: OS command injection through environment-controlled command construction
Risk Level: HighVulnerable Code
python CHROME_EXE = os.getenv( "CHROME_EXE", r"C:\Program Files\Google\Chrome\Application\chrome.exe" ) SRC_DIR = os.path.expandvars( os.getenv("CHROME_SRC_DIR", r"%LOCALAPPDATA%\Google\Chrome\User Data") ) DST_DIR = os.getenv( "CHROME_PROFILE_DIR", os.path.join(os.path.expandvars("%TEMP%"), "browser-use-chrome-profile") )python def start_chrome(): cmd = ( f'"{CHROME_EXE}"' f' --remote-debugging-port={PORT}' f' --remote-allow-origins=*' f' --user-data-dir="{DST_DIR}"' f' --profile-directory=Default' f' --no-first-run' f' --no-default-browser-check' ) subprocess.Popen(cmd, shell=True, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)Technical Analysis
CHROME_EXEandDST_DIRare populated from theCHROME_EXEandCHROME_PROFILE_DIRenvironment variables. These values are directly interpolated into a command string that is executed withshell=True.Quoting the values does not make this safe. A malicious value containing a quote followed by Windows command-shell metacharacters can terminate the intended argument and append another command. Because the resulting string is interpreted by the shell rather than passed directly to Chrome as an argument array, attacker-controlled environment data can alter the command structure.
This vulnerability is reachable whenever an attacker can influence the process environment, such as through a wrapper script, compromised launcher, shared automation configuration, CI environment, or poisoned shell profile.
Attack Path
- An attacker gains the ability to set or influence
CHROME_EXEor `CHROME_PROFILE ...[truncated 896 chars]
- An attacker gains the ability to set or influence
- Remediation
View remediation
Remediation Suggestions
-
Remove
shell=Trueand invoke Chrome using an argument list so values are never interpreted as command syntax:python cmd = [ CHROME_EXE, f"--remote-debugging-port={PORT}", "--user-data-dir=" + DST_DIR, "--profile-directory=Default", "--no-first-run", "--no-default-browser-check", ] subprocess.Popen( cmd, shell=False, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, ) -
Resolve the executable to an absolute path and verify that it exists and is a regular executable file.
-
Reject unexpected control characters and validate that the profile directory resolves to an approved user-owned location.
-
Validate
CDP_PORTto ensure it is within the valid TCP port range. -
Do not attempt to secure shell command construction through manual escaping alone; avoiding the shell is the appropriate control.
-
