Skip to content

Security: Univers42/darkly

Security

SECURITY.md

Security Audit — this deliverable

This documents the security posture of the artifact we ship (the report + build toolchain), not the Darkly target being audited. Every control below is enforced by make audit (and most by make all), so the claims are tested, not asserted.

Scope & threat model

  • Artifact: report/index.html — a single, static, self-contained file. No server, no backend, no runtime dependencies, no user input at runtime.
  • Toolchain: TypeScript sources built/tested in Docker (Node + Playwright browsers).
  • Primary risk: the report renders attacker-style payloads as content (breach write-ups literally contain <script>, <img onerror>, SQL). The main threat is self-XSS / DOM injection if any of that data reached an HTML sink unescaped. Secondary risks: external resource loading (privacy/integrity), and supply-chain risk in the build tools.
  • Out of scope: network/transport (static file), authn/z and sessions (none), server config.

Controls (mapped to OWASP Top 10 2021 / ASVS)

Control Standard How it's enforced / verified
Output encoding — all dynamic data HTML-escaped at the one templating boundary (src/html.ts); no raw() on untrusted data A03 Injection · ASVS V5.3 scripts/security-check.ts renders a hostile fixture and asserts every payload is inert; tests/security.spec.ts asserts exactly one <script>, zero inline handlers, no dialogs
No dangerous DOM sinks — no innerHTML/outerHTML/document.write/eval/new Function A03 · ASVS V5.2 grep gate in security-check.ts; enhancement uses textContent + addEventListener only
Strict Content-Security-Policy — hash-pinned inline <style>/<script>, default-src 'none', no unsafe-inline/unsafe-eval A05 Misconfiguration · ASVS V14.4.3 tests/security.spec.ts verifies directives + zero CSP violations while the script still runs
No inline style= (precondition for hash-only style-src) A05 · ASVS V14.4 security-check.ts asserts no style= in the report
No external / active resources — no CDN, no remote src/href, no javascript:; font is self-hosted base64 A05 / A08 · ASVS V14.4 security-check.ts regex gates; tests/gdpr.spec.ts asserts zero external requests
Referrer policy no-referrer A05 · privacy present in the report <head>
Privacy / RGPD — no cookies, no localStorage/sessionStorage, no analytics, no PII GDPR tests/gdpr.spec.ts
Supply chain — pinned versions + committed lockfile; production dependencies = 0 A06 Vulnerable Components npm audit --omit=dev = 0; full npm audit = 0
Build integrity — CI image pinned by digest; build/test run --network none A08 Integrity Failures docker/Dockerfile digest pin; Makefile isolates the network
Least privilege — containers run as the host UID, no-new-privileges, --cap-drop ALL, read-only rootfs (+tmpfs), no network for build/test A05 Makefile RUN/RUN_BROWSER

Residual notes

  • The report intentionally displays exploit payloads (that is its purpose). They are shown as text and are provably inert (escaping + CSP). This is content, not a vulnerability.

  • The CSP is delivered via <meta> (the only option for a file:// document). A meta CSP cannot emit violation reports and only governs content parsed after it. If this report is ever served, emit the policy as a response header and add the header-only controls. Ready-to-paste (nginx):

    add_header Content-Security-Policy "default-src 'none'; script-src 'sha256-…'; style-src 'sha256-…'; img-src 'none'; font-src data:; connect-src 'none'; object-src 'none'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'; require-trusted-types-for 'script'; trusted-types 'none'" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header X-Frame-Options "DENY" always;
    add_header Referrer-Policy "no-referrer" always;
    add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload" always;
    # Optional violation reporting:
    add_header Reporting-Endpoints 'csp="/csp-report"' always;
  • Dev-tooling advisories are tracked via full npm audit; the shipped artifact has zero runtime deps, so its supply-chain exposure is zero regardless of dev-tool churn.

Verify

make audit    # supply chain + artifact output-encoding + strict CSP + DOM-XSS suite
make all      # the above plus typecheck, lint, WCAG AA, RGPD, and the perf benchmark

There aren't any published security advisories