T09 · Insecure Skill Coding Practices
- Location
scripts/build_xlsx.py:162- Finding
Unrestricted spreadsheet formulas allow creation of active-content workbooks
- Content
View full analysis
Vulnerability Details
File Location:
scripts/build_xlsx.py:162-163andscripts/build_xlsx.py:439-440
Vulnerability Type: Arbitrary spreadsheet formula injection
Risk Level: MediumThe relevant validation and rendering code is:
python if c.get("formula") is not None and not isinstance(c["formula"], str): die(f"{tag}: 'formula' must be a string")python if col.get("formula"): td["formula"] = col["formula"]Technical Analysis
The validator only confirms that a supplied formula is a string. It does not parse the expression, restrict it to local structured references, or reject potentially dangerous constructs such as external workbook references, URLs, DDE-style expressions, or network-capable spreadsheet functions.
The formula is subsequently passed unchanged to XlsxWriter and embedded in the generated workbook. Consequently, anyone who controls or influences the input JSON specification can control active formula content in the resulting XLSX file.
The Python process does not execute the formula itself. Exploitation occurs when a recipient opens or recalculates the generated workbook in a spreadsheet client. The exact behavior depends on the client version, trust settings, protected-view configuration, and organizational policy. Modern clients may block dangerous behavior or display a warning, but the generator should not rely exclusively on recipient-side controls.
Attack Path
- An attacker gains the ability to provide or modify the JSON specification consumed through
--input. - The attacker places a malicious expression in a
columns[].formulafield. - Validation accepts the value because it is a string.
_render_sheetpasses the expression directly to XlsxWriter as the table-column formula.- The generated XLSX file is delivered to a user as a legitimate report.
- The recipient opens or recalculates the workbook.
- Depending on the spreadsheet client and its security configuration, the form ...[truncated 974 chars]
- An attacker gains the ability to provide or modify the JSON specification consumed through
- Remediation
View remediation
Remediation Suggestions
- Disable caller-supplied formulas by default when the JSON specification is not fully trusted.
- Add an explicit command-line option, such as
--allow-formulas, so active content requires deliberate authorization. - If formulas are required, parse them and permit only a narrowly defined grammar of local arithmetic and structured table references.
- Reject formulas containing external workbook references, URI schemes, DDE syntax, or other external-data constructs.
- Maintain a denylist as defense in depth for network-capable and legacy high-risk functions, while treating an allowlist parser as the primary control.
- Enforce a maximum formula length and reject control characters or malformed expressions.
- Record in the output summary whether active formulas were embedded.
- Document that workbooks containing formulas should only be generated from trusted specifications and should be opened under protected-view and external-content restrictions.
- Add automated tests demonstrating rejection of external references, URLs, DDE-style payloads, and unsupported functions.
