T09 · Insecure Skill Coding Practices
Warning
- Location
- scripts/media_manifest.py:16
- Finding
- CSV Formula Injection Through Untrusted File Names and Paths## Vulnerability Details **File Location**: `scripts/media_manifest.py`, lines 16–17 and 24–27 **Vulnerability Type**: CSV formula injection **Risk Level**: Medium ### Vulnerable Code ```python rows.append({ "path": str(p), "filename": p.name, "ext": p.suffix.lower(), "size_bytes": stat.st_size, "created_at": getattr(stat, "st_ctime", ""), "modified_at": getattr(stat, "st_mtime", "") }) fields = ["path","filename","ext","size_bytes","created_at","modified_at"] with open(args.out, "w", encoding="utf-8", newline="") as f: w = csv.DictWriter(f, fieldnames=fields) w.writeheader() w.writerows(rows) ``` ### Technical Analysis The script recursively collects attacker-influenced file names and paths and writes them directly into CSV cells. A malicious file name beginning with a spreadsheet formula marker such as `=`, `+`, `-`, or `@` can be interpreted as a formula when the generated manifest is opened in spreadsheet software. CSV quoting performed by `csv.DictWriter` preserves CSV structure but does not reliably prevent spreadsheet applications from evaluating cell contents as formulas. The vulnerability therefore crosses a trust boundary between the local filesystem and the spreadsheet application used to inspect the generated artifact. ### Attack Path 1. An attacker creates or supplies a media directory containing a file whose name begins with a formula marker and contains a spreadsheet formula payload. 2. The user runs `media_manifest.py` against that directory. 3. The script reads the malicious name through `p.name` and its corresponding path through `str(p)`. 4. The values are written unchanged to the output CSV. 5. The user opens the manifest in spreadsheet software that evaluates formula-like cells. 6. Depending on the spreadsheet application and its security configuration, the formula may initiate an external request, disclose data represented in accessible cells, or display deceptive content. ### Impact Assessment ...[truncated 506 chars]
- Remediation
- ## Remediation Suggestions 1. Sanitize every string value before writing it to CSV, particularly `path`, `filename`, and `ext`. 2. For values whose first non-whitespace character is `=`, `+`, `-`, or `@`, prefix the value with an apostrophe or use another neutralization strategy compatible with the intended spreadsheet applications. 3. Consider also treating tab, carriage-return, and line-feed prefixes conservatively because spreadsheet import behavior varies. 4. Keep normal CSV escaping through `csv.DictWriter`; formula neutralization complements rather than replaces CSV quoting. 5. Document that generated manifests contain untrusted filesystem metadata and should be imported with formula evaluation disabled where possible. 6. Add regression tests using malicious names such as `=payload.jpg`, `+payload.png`, `-payload.mov`, and `@payload.gif`, then verify that no exported cell begins with an active formula marker. A centralized sanitizer can be applied before serialization: ```python def safe_csv_cell(value): if not isinstance(value, str): return value if value.lstrip().startswith(("=", "+", "-", "@")): return "'" + value return value safe_rows = [ {key: safe_csv_cell(value) for key, value in row.items()} for row in rows ] w.writerows(safe_rows) ```
