T05 · Unauthorized Access and Privilege Escalation
- Location
scripts/bootstrap_project.py:1230- Finding
Arbitrary Filesystem Writes Through an Unvalidated Project Key
- Content
View full analysis
Vulnerability Details
File Location:
scripts/bootstrap_project.py:1230-1233
Additional Location:scripts/bootstrap_project.py:859-863,scripts/bootstrap_project.py:141-143
Vulnerability Type: Path traversal and unrestricted destination path
Risk Level: HighVulnerable Code
python key = args.project_key root = WORKSPACE / key threads = parse_thread_ids(args.thread_ids) if args.thread_ids else {} if root.exists(): print(f"ERROR: {root} already exists") sys.exit(1)The interactive bootstrap path uses the same unsafe construction:
python def _do_fix_and_continue(args): from pathlib import Path project_dir = Path(WORKSPACE) / args.project_key project_dir.mkdir(parents=True, exist_ok=True) # Build minimal ctx and write filesFiles subsequently created under the selected destination are also made executable:
python for script in (root / "scripts").glob("*.sh"): script.chmod(0o755) for script in (root / "scripts").glob("*.py"): script.chmod(0o755)Technical Analysis
args.project_keyis joined directly toWORKSPACEwithout centralized validation or a containment check. Although interactive collection applies a limited slug validator, the documented direct command-line interface does not apply that validator.pathlib.Pathpermits both traversal components and absolute operands. Values such as../../attacker-selected-directorycan escape the projects directory after path resolution. Ifargs.project_keyis absolute,WORKSPACE / args.project_keyresolves to the supplied absolute path and discards the intended workspace prefix.The script then creates directories, writes the generated scaffold, and marks generated Python and shell files executable. The
root.exists()check prevents the normal direct-bootstrap branch from targeting an already-existing root directory, but it does not prevent creation in a ...[truncated 1465 chars]- Remediation
View remediation
Remediation Suggestions
-
Implement one centralized validator and invoke it in every operating mode, including direct CLI, interactive, fix, and continue modes.
-
Restrict project keys to a strict pattern such as:
python import re PROJECT_KEY_PATTERN = re.compile(r"^[a-z0-9]+(?:-[a-z0-9]+)*$") def validate_project_key(value: str) -> str: if not PROJECT_KEY_PATTERN.fullmatch(value): raise ValueError( "project_key must contain only lowercase letters, digits, and internal hyphens" ) return value -
Resolve and verify destination containment before creating anything:
python workspace = WORKSPACE.resolve() project_key = validate_project_key(args.project_key) destination = (workspace / project_key).resolve() if destination.parent != workspace: raise ValueError("Project destination escapes WORKSPACE") -
Reject absolute paths, path separators,
.and..components explicitly. -
Do not use
exist_ok=Truefor new project creation unless the operation is explicitly an update and the destination has been positively identified as an existing scaffold. -
Create the project in a temporary directory under
WORKSPACE, validate it, and atomically rename it to the final destination. -
Avoid assigning executable permissions until generated content has passed validation.
-
