Skip to content

Omnibus v1.1.0-beta.054

Choose a tag to compare

@github-actions github-actions released this 25 Jun 19:01
· 4 commits to main since this release

v1.1.0-beta.054 - fix(security): XSS + SSRF + path-traversal hardening from the full audit

🧼 Stored XSS in the series synopsis (audit High #3)

  • The series page renders provider descriptions via dangerouslySetInnerHTML, but /api/library/issue and /api/library/series returned raw ComicVine/Metron HTML — a poisoned description executed in the viewer's session. Both now run descriptions through the existing sanitizeDescription() (sanitize-html) on the way out, cleaning fresh AND already-stored data

🚧 sanitizeFilename path traversal (audit Medium #12)

  • sanitizeFilename stripped <>:"/|?* but not dots, so an untrusted ComicInfo field of ".." became a real parent-dir segment once joined into a folder path (arbitrary write location). Now strips leading/trailing dots and collapses an all-dots value to "_"; interior dots (Vol.1, "Mr. Robot") are preserved

🌐 SSRF guards on server-side fetches of untrusted URLs (audit Medium #9, #10)

  • New src/lib/utils/ssrf.ts: assertSafeFetchUrl rejects non-http(s) schemes and loopback/private/link-local hosts (169.254.169.254, localhost, RFC1918, IPv6 ULA/link-local, obfuscated decimal IPs); assertSafeRedirect re-validates each axios redirect hop
  • CBL import: guards the user-supplied URL, blocks redirects, adds a timeout + body-size cap
  • Download pipeline (addDownload + downloadDirectFile): guards scraped/indexer URLs before fetch and constrains maxRedirects with per-hop re-validation

🧪 Tests

  • ssrf host/url blocking (incl. decimal-IP + 172.16/12 boundaries); sanitizeFilename traversal; CBL refuses an internal SSRF target without fetching

✅ Verification

  • tsc clean; eslint . 0 errors; vitest 264 passed (+9)