T09 · Insecure Skill Coding Practices
- Location
scripts/install.py:76- Finding
Shell Command Injection Through an Unquoted Verification Path
- Content
View full analysis
Vulnerability Details
File Location:
scripts/install.py, lines 76–79
Vulnerability Type: OS command injection
Risk Level: HighVulnerable Code
python verify_path = Path(__file__).parent.parent / "verify.py" if verify_path.exists(): print("\n🔍 Verifying installation...") os.system(f"python {verify_path}")Technical Analysis
The installer constructs a shell command by interpolating
verify_pathdirectly into a string passed toos.system. Becauseos.systeminvokes a command shell and the path is not quoted or escaped, shell metacharacters contained in the project directory path can be interpreted as command syntax rather than as part of the filename.Although the path is derived from
__file__, an attacker may control it by placing or extracting the project beneath a specially crafted directory name. Exploitation also requires a file to exist at the computed<project-root>/verify.pypath. The audited package normally contains the verifier atscripts/verify.py, so this condition is not met in the package as reviewed; however, an attacker controlling the containing project tree can add the expected file and trigger the vulnerable call.Attack Path
- An attacker prepares or extracts the project beneath a directory whose name contains shell metacharacters and an injected command.
- The attacker places a file at the computed
<project-root>/verify.pylocation so that theverify_path.exists()condition succeeds. - The attacker convinces a victim to execute
scripts/install.py. - After installation, the script interpolates the crafted path into
python {verify_path}. os.systempasses the resulting string to the platform shell.- The shell parses the metacharacters and executes the attacker-supplied command with the victim's privileges.
Impact Assessment
Successful exploitation permits arbitrary command execution under the account running the insta ...[truncated 429 chars]
- Remediation
View remediation
Remediation Suggestions
Avoid invoking a shell. Execute the verifier with an argument array and the current Python interpreter:
python import subprocess verify_path = Path(__file__).resolve().parent / "verify.py" if verify_path.is_file(): print("\n🔍 Verifying installation...") subprocess.run( [sys.executable, str(verify_path)], check=True, )This approach prevents shell metacharacters in paths from being interpreted as command syntax. It also corrects the verifier location: the packaged verifier is
scripts/verify.py, in the same directory asinstall.py, rather than at the project root.Additional hardening should include:
- Resolve and validate the verifier path before execution.
- Require it to be a regular file and reject unexpected symbolic links where the trust model requires that restriction.
- Propagate verification failures by using
check=Trueand handlingsubprocess.CalledProcessError. - Do not attempt to fix the issue solely through manual quoting; shell-free process invocation is safer and cross-platform.
- Add tests using project paths containing spaces and shell metacharacters.
