T09 · Insecure Skill Coding Practices
- Location
scripts/visualize.py:256- Finding
COCO Filename Path Traversal Enables Arbitrary Image File Access and Overwrite
- Content
View full analysis
Vulnerability Details
File Location:
scripts/visualize.py, lines 256-258 and 285
Vulnerability Type: Unvalidated path traversal and absolute-path injection
Risk Level: HighVulnerable Code
python img_info = images.get(img_id, {}) img_name = img_info.get('file_name', f'{img_id}.jpg') img_path = images_dir / img_name if not img_path.exists(): continuepython output_path = output_dir / img_name visualize_image( str(img_path), annotations, str(output_path), thickness=args.thickness, fill=args.fill, show_label=args.show_label, font_size=args.font_size )The destination is subsequently created and written in
visualize_image:python os.makedirs(os.path.dirname(output_path) if os.path.dirname(output_path) else '.', exist_ok=True) img.save(output_path)Technical Analysis
The COCO
file_nameproperty is taken directly from an attacker-controlled JSON annotation and used to construct both input and output paths. The code does not reject absolute paths,..path components, or resolved paths outside the configured image and output directories.With
pathlib, joining a base path to an absolute second operand discards the base path. Relative traversal components can similarly escape the intended directory after path resolution. Consequently,img_pathcan refer to any image file readable by the invoking user, whileoutput_pathcan refer to a location outside the designated output directory.The output function also creates missing parent directories and saves the rendered image without checking whether the destination remains within the approved output directory.
Attack Path
- An attacker prepares a COCO JSON document containing an image entry whose
file_nameis an absolute path or includes traversal components, such as/home/user/important.pngor../../important.png. - The victim invokes the documented command:
ba
...[truncated 1359 chars]
- An attacker prepares a COCO JSON document containing an image entry whose
- Remediation
View remediation
Remediation Suggestions
Treat every COCO
file_namevalue as untrusted input:- Reject absolute filenames.
- Resolve the candidate input and output paths before accessing them.
- Verify with
Path.relative_to()orPath.is_relative_to()that each resolved path remains under its authorized base directory. - Reject filenames containing parent-directory traversal components.
- Use a sanitized basename or an internally generated filename for output rather than reproducing the input path.
- Refuse to overwrite existing output files unless explicitly authorized.
- Avoid automatically creating directories derived from untrusted filenames.
Example hardening pattern:
python images_root = Path(args.images).resolve() output_root = Path(args.output).resolve() supplied_name = Path(img_name) if supplied_name.is_absolute() or ".." in supplied_name.parts: raise ValueError(f"Unsafe COCO filename: {img_name}") input_path = (images_root / supplied_name).resolve() if not input_path.is_relative_to(images_root): raise ValueError(f"Input path escapes images directory: {img_name}") safe_output_name = supplied_name.name output_path = (output_root / safe_output_name).resolve() if not output_path.is_relative_to(output_root): raise ValueError(f"Output path escapes output directory: {img_name}")Where support for older Python versions is required, replace
is_relative_to()with a guardedrelative_to()call.
