T09 · Insecure Skill Coding Practices
Error
- Location
- scripts/converter.py:71
- Finding
- Path Traversal Enables Arbitrary TXT File Overwrite<![CDATA[ ## Vulnerability Details **File Location**: `scripts/converter.py`, lines 71-90 **Vulnerability Type**: Path traversal and arbitrary file overwrite **Risk Level**: High ### Vulnerable Code ```python # Get base name without extension base_name = os.path.splitext(img_name)[0] output_path = os.path.join(output_dir, f"{base_name}.txt") with open(output_path, 'w') as f: for ann in anns: category_id = ann['category_id'] bbox = ann['bbox'] # [x, y, w, h] # Convert to YOLO format (center_x, center_y, w, h) normalized x_center = (bbox[0] + bbox[2] / 2) / width y_center = (bbox[1] + bbox[3] / 2) / height w = bbox[2] / width h = bbox[3] / height # YOLO uses 0-indexed class IDs f.write(f"{category_id - 1} {x_center} {y_center} {w} {h}\n") ``` ### Technical Analysis The value assigned to `img_name` originates from the untrusted COCO `images[].file_name` field. The code removes only the extension and then joins the remaining value directly to the user-selected output directory. No validation removes parent-directory components, rejects absolute paths, or verifies that the resolved destination remains inside `output_dir`. For example, a value such as `../../target.txt` produces a destination ending in `../../target.txt`. An absolute path can also cause `os.path.join()` to discard the intended output directory entirely. The destination is opened using mode `w`, which creates a missing file or truncates an existing file. Exploitation is constrained to paths writable by the operating-system account running the converter and to filenames ending in `.txt`. ### Attack Path 1. An attacker creates or modifies a COCO annotation file. 2. The attacker places a traversal or absolute path in an `images[].file_name` value, such as `../../configuration.txt`. 3. The attacker causes a user or automated conversion process to run COCO-to-YOLO conversion on that file. 4. `os.path.splitext()` preserve ...[truncated 664 chars]
- Remediation
- <![CDATA[ ## Remediation Suggestions - Treat every COCO `file_name` value as untrusted. - Reduce the supplied filename to a leaf name with `Path(img_name).name` when directory preservation is unnecessary. - Explicitly reject absolute paths and values containing parent-directory components. - Resolve both the output root and candidate destination, then verify that the candidate is contained within the output root. - Refuse to overwrite existing files by default, or require an explicit overwrite option. - Add tests covering absolute paths, `../` traversal, nested traversal, and platform-specific path separators. Example hardening approach: ```python output_root = Path(output_dir).resolve() safe_name = Path(img_name).name base_name = Path(safe_name).stem output_path = (output_root / f"{base_name}.txt").resolve() if output_root not in output_path.parents: raise ValueError("Unsafe output path") with output_path.open("x", encoding="utf-8") as f: ... ``` If overwriting is a required feature, replace mode `x` only after obtaining explicit user authorization. ]]>
