T09 · Insecure Skill Coding Practices
- Location
scripts/capture_webcam.py:80- Finding
Path Traversal and Arbitrary File Overwrite Through Unsanitized Filename Prefix
- Content
View full analysis
Vulnerability Details
File Location:
scripts/capture_webcam.py, lines 80-114
Vulnerability Type: Path traversal and arbitrary file overwrite
Risk Level: HighVulnerable Code
python parser.add_argument("--prefix", default="shot", help="Filename prefix (default: 'shot')") args = parser.parse_args() # Setup output directory output_dir = args.output_dir or get_default_output_dir() os.makedirs(output_dir, exist_ok=True) # ... filename = f"{args.prefix}{i}.jpg" path = os.path.join(output_dir, filename) if not cv2.imwrite(path, frame): print(f"ERROR: Failed to write {path}", file=sys.stderr) cap.release() sys.exit(3)Technical Analysis
The user-controlled
--prefixvalue is incorporated directly into the destination path without rejecting absolute paths, directory separators, or parent-directory components.os.path.join()does not guarantee that the resulting path remains beneathoutput_dir. An absolute prefix can discard the intended base directory, while a prefix containing../can traverse outside it.cv2.imwrite()writes to the resolved path and can overwrite an existing writable file. The code also does not check for symbolic links, pre-existing files, or path collisions.Attack Path
- An attacker controls or influences the arguments used to invoke the capture script.
- The attacker supplies a prefix containing traversal components, such as
--prefix ../../target. - The script constructs a path equivalent to
<output-dir>/../../target1.jpg. - Path resolution escapes the intended capture directory.
cv2.imwrite()creates or overwrites the attacker-selected user-writable file with JPEG data.- If a relevant path is a symbolic link, the write may be redirected to another writable destination.
Impact Assessment
Exploitation grants arbitrary file creation or overwrite with image data within the privileges ...[truncated 265 chars]
- Remediation
View remediation
Remediation Suggestions
- Restrict
--prefixto a safe basename character set, such as letters, digits, underscores, and hyphens. - Reject absolute paths,
.and..components, directory separators, and platform-specific alternate separators. - Resolve both the output directory and candidate destination with
pathlib.Path.resolve(), then verify that the destination remains beneath the resolved output directory. - Generate filenames internally with UUIDs or trusted timestamps rather than accepting path-like user input.
- Refuse to overwrite existing files or use exclusive file creation.
- Where symbolic-link attacks are relevant, open files with operating-system protections such as
O_NOFOLLOWand write through the safely opened descriptor.
Example validation:
python import re from pathlib import Path if not re.fullmatch(r"[A-Za-z0-9_-]+", args.prefix): parser.error("--prefix may contain only letters, digits, underscores, and hyphens") base = Path(output_dir).resolve() destination = (base / f"{args.prefix}{i}.jpg").resolve() if base not in destination.parents: raise ValueError("Output path escapes the configured output directory") if destination.exists(): raise FileExistsError(f"Refusing to overwrite: {destination}")- Restrict
