Security [MEDIUM]: Dispo workbook path unvalidated + image upload polyglot risk #54
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
(1)
workbookPathSchemaaccepts any absolute path ending in.xlsx; consumer usespath.resolve()without base-directory check. Admin can trigger parsing of arbitrary.xlsxanywhere the process can read. ExcelJS has had zip-slip/XXE CVEs. (2)validateImageDataUrlchecks only first 18 bytes — polyglot PNG/SVG files pass magic-byte check but contain HTML/SVG tail → stored XSS if ever served without strict MIME.Evidence
packages/application/src/use-cases/dispo-import/read-workbook.ts:60-85 — path.resolve without allowlistpackages/api/src/lib/image-validation.ts — only 24-base64-char prefix checkpackages/api/src/router/project-cover.ts:117 — Gemini-generated covers skip validateImageDataUrl entirelyImpact
(1) Admin (or compromised admin) can reach parser CVE on arbitrary filesystem. (2) Stored XSS via polyglot image.
Proposed Fix
(1) Require import path relative to configured IMPORT_DIR via
path.relative(IMPORT_DIR, resolved).startsWith('..')check. Reject absolute paths from client. (2) Re-encode all uploaded images throughsharpto canonical PNG/JPEG; never round-trip raw data URL. Apply validation to Gemini-generated covers too.Acceptance Criteria
Parent Epic: #1
Source: Full-Codebase Security Audit 2026-04-16 (B-7, B-9)
Resolved in commit
c4b01c1bfcon branchsecurity/audit-2026-04-17.What changed
Dispo workbook path allowlist
DISPO_IMPORT_DIRenv var (defaults to./imports) pins the root for workbook reads.workbookPathSchema) rejects absolute paths and any segment equal to...read-workbook.tsre-validates containment at runtime usingpath.relative.Image upload / provider-image polyglot defence
validateImageDataUrlnow checks the full 8-byte PNG magic, enforces PNG IEND and JPEG FFD9 trailers, scans the decoded buffer for markup polyglot markers (<script,<svg,<iframe,<object,<embed,<html,<!doctype,javascript:,onerror=,onload=), and explicitly rejects SVG.Tests
packages/api/src/__tests__/image-validation.test.tswith 10 cases.Docs
docs/security-architecture.md§5 updated..env.exampledocumentsDISPO_IMPORT_DIR.Closing.