Skip to content

Security: umaadi/Toolsplate

Security

docs/SECURITY.md

SECURITY.md — Threat model, controls, and per-gate scan results

Threat model (summary)

CyberToolHub ships hundreds of "paste your input" and payload-generator tools. The dominant risks are self-XSS / DOM injection (untrusted input reaching an HTML sink), ReDoS / browser DoS (user regex, huge input), prototype pollution (parsing user JSON/YAML), and — for any future server features — SSRF / open proxy. The site itself must not be hackable.

Primary assets

  • The user's pasted data / secrets / BYOK keys (must never leave the browser to a Umaadi server).
  • The integrity of the served pages (no injected/executed attacker script).

Trust boundaries

  • All Phase 1/2 tool logic runs client-side; the network boundary is only crossed by explicitly documented CORS-friendly FAPI calls and BYOK→provider calls.
  • No Umaadi backend exists in the static build. Server-class features are feature-flagged OFF.

Controls

Risk Control Where
XSS / DOM injection Output written with textContent only; no innerHTML/document.write; no inline event handlers src/lib/dom.ts, every tool script
XSS via URL prefill URL params read as data only, length-capped, never reflected as HTML src/lib/sanitize.ts readParam
Code execution No eval/new Function/setTimeout(string); safe parsers only enforced repo-wide
Prototype pollution safeJsonParse + stripPollutionKeys reject __proto__/constructor/prototype src/lib/sanitize.ts
ReDoS / DoS Web-Worker execution with hard timeout + input-size caps for user-regex/large input src/lib/worker-runner.ts, src/lib/limits.ts
Oversized input TEXT_MAX/FILE_MAX caps before processing src/lib/limits.ts
Clickjacking X-Frame-Options: DENY + CSP frame-ancestors 'none' public/_headers
Content injection Strict CSP: default-src 'self', hashed script-src/style-src, object-src 'none', base-uri 'none' astro.config.mjs (meta) + _headers
Secret exfiltration BYOK keys in localStorage only; assertDirectProvider blocks same-origin sends src/lib/byok-client.ts
Payload execution Generated payloads rendered as inert text in <pre>; "authorized testing only" notice src/components/ToolShell.astro
Supply chain Exact-pinned deps + lockfile; npm audit clean at each gate package.json, CI scripts

Scan results per gate

Phase 0 gate (foundation)

  • npm audit: 0 vulnerabilities (after pinning esbuild 0.28.1).
  • Unit tests: base64 suite 29/29 pass (incl. XSS-as-data, prototype-pollution-as-data, size-cap).
  • Build: astro build clean, 140 pages, strict hashed CSP present on every page.
  • Manual review: inline scripts are hash-allowlisted (no unsafe-inline); no innerHTML in src/lib.
  • Semgrep / Gitleaks: to be run as part of the local CI scripts before the first tagged commit — see GAPS_TRACKER.md G1.

Definition-of-Done gate (CLOSED — 125 tools)

  • npm audit: 0 vulnerabilities (overrides: esbuild 0.28.1, yaml 2.9.0).
  • Unit + adversarial: 415/415 pass.
  • astro check (strict TypeScript across 248 files): 0 errors.
  • astro build: clean, 140 pages, hashed strict CSP on every page; connect-src scoped to the 5 allowlisted public APIs; worker-src 'self'.
  • Manual SAST (repo-wide grep): 0 real occurrences of innerHTML/outerHTML/insertAdjacentHTML/ document.write/eval(/new Function/dangerouslySetInnerHTML on data (only a comment + a csp-analyzer warning string match).
  • Secret scan (repo-wide grep): 0 private keys / API keys / tokens committed (only PEM-format documentation strings). .env*/*.pem/*.key gitignored.
  • Bundle scan: no plaintext shell payloads (base64-encoded, D9); lone WebAssembly token is an openpgp error-string check.
  • E2E (Playwright, real Chromium): 4/4 pass — zero console/CSP errors on the landing + base64 pages; XSS payload page never executes alert (inert text confirmed live); file-hash tool issues zero external network requests. (GAPS G2 CLOSED.)
  • Semgrep/Gitleaks: not runnable on this Windows host (no wheel/binary) → GAPS G1 (Low); run in deploy CI/Docker.

Phase 1 gate (CLOSED — 61 tools)

  • npm audit: 0 vulnerabilities (12 runtime deps incl. openpgp, @peculiar/x509, js-yaml, exifr, qrcode-generator, bcryptjs, js-sha3 — all pinned).
  • Unit + adversarial: 300/300 pass across encoding, hashing, crypto/certs, converters, password, network, cvss, jwt, forensics.
  • Build: clean, hashed CSP on every page, no unsafe-inline/unsafe-eval; worker-src 'self' for the ReDoS regex worker.
  • Runtime hazard scan: no eval/new Function in any bundle; WebAssembly token is openpgp error-string handling, not wasm instantiation.
  • Manual XSS/DOM review: pass — all dynamic output via textContent/DOM APIs/CSSOM/DOMParser.
  • Semgrep/Gitleaks: deferred (GAPS G1, Low). E2E: deferred (GAPS G2, Low).

Update this section at every phase gate with Semgrep (0 C/H/M), audit (0 C/H/M), Gitleaks (clean), manual XSS/DOM review (pass), adversarial suite (pass).

There aren't any published security advisories