T09 · Insecure Skill Coding Practices
Error
- Location
- scriptBackend.py:141
- Finding
- Shell Command Injection Through Unsanitized Project Parameters<![CDATA[ ## Vulnerability Details **File Location**: `scriptBackend.py`, lines 141–160 **Vulnerability Type**: OS command injection **Risk Level**: High ### Vulnerable Code ```python path = input(f'{color.YELLOW}Desired path of this project: {color.END}') 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 commands executed by `os.system`. This function invokes a system shell, so shell metacharacters contained in those values are interpreted as command syntax rather than literal argument content. The existence check on `path` does not make it safe for shell use. A valid path can still contain shell metacharacters. No equivalent validation is performed for project or application names. In addition to command injection, the absence of argument-safe execution causes ordinary paths containing spaces or other shell-sensitive characters to behave incorrectly. The `source .venv/bin/activate` command also executes in a temporary child shell. Its environment changes do not persist into subsequent commands, so later package operations may affect the invo ...[truncated 1159 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Replace every `os.system` invocation involving dynamic data with `subprocess.run` using an argument list and `check=True`. - Validate Django project and application names with a strict Python-identifier allowlist, such as `^[A-Za-z_][A-Za-z0-9_]*$`, and reject Python keywords. - Resolve and manipulate paths using `pathlib.Path`; do not construct paths through raw string concatenation. - Invoke virtual-environment tools directly rather than attempting to activate the environment in a child shell. - Report subprocess failures instead of suppressing them or continuing after unsuccessful setup operations. Example: ```python import keyword import re import subprocess from pathlib import Path IDENTIFIER = re.compile(r"^[A-Za-z_][A-Za-z0-9_]*$") def validate_identifier(value): if not IDENTIFIER.fullmatch(value) or keyword.iskeyword(value): raise ValueError("Invalid Django identifier") return value base_path = Path(path).resolve() projectName = validate_identifier(projectName) appName = validate_identifier(appName) venv_python = base_path / ".venv" / "bin" / "python" subprocess.run( [str(venv_python), "-m", "django", "startproject", projectName], cwd=base_path, check=True, ) subprocess.run( [str(venv_python), "manage.py", "startapp", appName], cwd=base_path / projectName, check=True, ) ``` ]]>
