T09 · Insecure Skill Coding Practices
- Location
scripts/export_triples.py:22- Finding
Spreadsheet Formula Injection in TSV Export
- Content
View full analysis
Vulnerability Details
File Location:
scripts/export_triples.py, lines 22–27
Vulnerability Type: Spreadsheet formula injection caused by unsafe TSV serialization
Risk Level: MediumVulnerable Code
python def export_tsv(triples, output): with open(output, "w", encoding="utf-8", newline="") as f: writer = csv.DictWriter(f, fieldnames=["subject", "predicate", "object", "evidence", "confidence"], delimiter="\t") writer.writeheader() for row in triples: writer.writerow({k: row.get(k) for k in writer.fieldnames})Technical Analysis
The TSV exporter writes extracted values directly into spreadsheet-compatible cells without neutralizing formula-leading characters. Extracted fields such as
subject,predicate,object, andevidencemay contain attacker-controlled text.When a cell begins with a character such as
=,+,-, or@, spreadsheet applications may interpret it as a formula rather than plain text. CSV or TSV quoting alone does not reliably prevent formula evaluation because spreadsheet applications can still evaluate quoted cell contents after parsing them.Attack Path
- An attacker supplies source text containing a formula-like value in an entity, attribute, relation, or evidence field.
- The extraction pipeline preserves that value in a generated triple.
- A user invokes
export_triples.pywith--format tsv. - The malicious value is written into the TSV file without formula neutralization.
- The user opens the exported TSV file in spreadsheet software.
- The spreadsheet may evaluate the value as a formula under its applicable security policy.
Impact Assessment
Successful exploitation occurs in the context of the user opening the exported file, not in the Python process itself. Depending on the spreadsheet application and its security configuration, formula execution may:
- Initiate external network requests and disclose data through request parameters ...[truncated 448 chars]
- Remediation
View remediation
Remediation Suggestions
Neutralize every untrusted string before writing spreadsheet-compatible output:
- Detect cells whose first non-whitespace character is
=,+,-, or@. - Prefix dangerous values with a single quote or use another escaping strategy explicitly supported by the intended spreadsheet applications.
- Apply neutralization to all exported string fields, including
subject,predicate,object, andevidence. - Consider tab, carriage-return, newline, and Unicode-based bypasses when implementing validation.
- Preserve a separate machine-oriented JSON or JSONL export when exact, unmodified values are required.
- Document that exported records contain untrusted data and should not be opened with formula execution enabled.
- Add tests covering formula payloads, leading whitespace, multiline values, and each formula-triggering prefix.
Example hardening approach:
python FORMULA_PREFIXES = ("=", "+", "-", "@") def sanitize_tsv_cell(value): if not isinstance(value, str): return value stripped = value.lstrip() if stripped.startswith(FORMULA_PREFIXES): return "'" + value return value def export_tsv(triples, output): fields = ["subject", "predicate", "object", "evidence", "confidence"] with open(output, "w", encoding="utf-8", newline="") as f: writer = csv.DictWriter(f, fieldnames=fields, delimiter="\t") writer.writeheader() for row in triples: writer.writerow({ key: sanitize_tsv_cell(row.get(key)) for key in fields })- Detect cells whose first non-whitespace character is
