T09 · Insecure Skill Coding Practices
Error
- Location
- scriptBackend.py:151
- Finding
- OS Command Injection Through Unvalidated Project Inputs<![CDATA[ ## Vulnerability Details **File Location**: `scriptBackend.py`, lines 151–171 **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```python if os.path.isdir(path) and os.path.exists(path): answer = input(f'{color.YELLOW}Would you like to create a venv in the desired directory: {color.END}') if answer.lower() == 'yes' or answer.lower() == 'y': os.system(f'python3 -m venv {path}.venv') loading('Creating Virtual Envirement', 1) projectName = input(f'{color.YELLOW}Choose a name for your project: {color.END}') if os.path.exists(f'{path}{projectName}'): print(f'{color.RED}Directory exists !{color.END}') exit(1) os.chdir(path) os.system('source .venv/bin/activate') run_command('pip install django') os.system(f'django-admin startproject {projectName}') os.chdir(f'{path}{projectName}') appName = input(f'{color.YELLOW}Choose a name for your app: {color.END}') os.system(f'django-admin startapp {appName}') ``` ### Technical Analysis The user-controlled `path`, `projectName`, and `appName` values are interpolated directly into strings passed to `os.system()`. This API executes its input through a command shell. Consequently, shell control operators, substitutions, redirections, and other metacharacters in these values are interpreted as command syntax rather than literal arguments. The checks performed on `path` only establish whether the supplied path exists and is a directory. They do not safely quote the value or prevent shell interpretation. No validation is applied to `projectName` or `appName`. ### Attack Path 1. An attacker or untrusted user starts the interactive bootstrap script. 2. The attacker provides a valid base directory. 3. When prompted for a project or application name, the attacker supplies a value containing shell syntax that terminates or extends the intended `django-admin` command. 4. The value is incorporated in ...[truncated 850 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Replace every interpolated `os.system()` call with `subprocess.run()` using an argument list and `check=True`: ```python subprocess.run( [sys.executable, "-m", "venv", str(venv_path)], check=True, ) subprocess.run( [str(venv_python), "-m", "django", "startproject", project_name], check=True, ) ``` - Validate project and application names against Django/Python identifier requirements, for example `^[A-Za-z_][A-Za-z0-9_]*$`. - Reject Python keywords and names that Django does not accept. - Construct paths with `pathlib.Path` rather than string concatenation. - Resolve the target path and verify that generated directories remain beneath the intended base directory. - Do not rely on shell quoting as the primary defense; eliminate shell evaluation entirely. ]]>
