T09 · Insecure Skill Coding Practices
- Location
scripts/clawhub_monitor.py:246- Finding
CSV Formula Injection in Exported Skill Metadata
- Content
View full analysis
Vulnerability Details
File Location:
scripts/clawhub_monitor.py, lines 246-250
Vulnerability Type: CSV formula injection
Risk Level: MediumVulnerable Code
python with open(output_file, "w", newline="", encoding="utf-8") as f: writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() for row in skills: writer.writerow({k: row.get(k) for k in fieldnames})The exported fields include remotely sourced package metadata such as
name,display_name,owner_handle, andsummary. These values are populated from ClawHub API responses inscripts/clawhub_monitor.py, lines 140-163, and reachwriter.writerow()without spreadsheet-formula neutralization.Technical Analysis
CSV quoting protects the file structure but does not prevent spreadsheet applications from interpreting cell content as formulas. If attacker-controlled package metadata begins with characters such as
=,+,-,@, a tab, or a carriage return, compatible spreadsheet software may evaluate it when a user opens the exported CSV.An attacker who controls public ClawHub package metadata could therefore embed a formula payload in a package name, display name, owner handle, or summary. The application would retrieve the value and preserve it in the CSV without adding a safe prefix or otherwise neutralizing it.
Attack Path
- An attacker publishes or modifies public ClawHub package metadata so that an exported field begins with a spreadsheet formula-control character.
- A victim queries the attacker-controlled owner or otherwise retrieves that package through the public API.
- The victim invokes the script with
--export, causing the untrusted metadata to be written directly to a CSV cell. - The victim opens the generated CSV in spreadsheet software that evaluates formulas.
- The embedded formula executes within the spreadsheet application's security context.
Impact Assessment
Successful exploitation requires a ...[truncated 698 chars]
- Remediation
View remediation
Remediation Suggestions
Sanitize every remotely sourced string before writing it to CSV:
- Detect values whose first character is
=,+,-,@, tab, or carriage return. - Prefix those values with an apostrophe or apply another neutralization method appropriate for the supported spreadsheet applications.
- Perform sanitization on all exported fields rather than only currently known free-text fields, because future API values may also become attacker-controlled.
- Preserve the original unsanitized values in JSON or text output only where those output contexts do not interpret formulas.
- Add automated tests for each dangerous prefix, including values containing leading whitespace followed by a formula marker.
- Document that CSV exports contain untrusted public metadata and should not be opened with formula execution enabled.
A centralized helper can enforce consistent handling:
python def sanitize_csv_cell(value: Any) -> Any: if isinstance(value, str): candidate = value.lstrip() if candidate.startswith(("=", "+", "-", "@", "\t", "\r")): return "'" + value return value # ... writer.writerow({ key: sanitize_csv_cell(row.get(key)) for key in fieldnames })- Detect values whose first character is
