Security
SO-CRATES is designed to run locally/self-hosted for an analyst examining potentially malicious files. What's built in by default (see Security Model for implementation details - function names, exact mechanisms):
- Network binding -
127.0.0.1by default; only the Docker/Podman image binds0.0.0.0internally (for port-publishing), with actual exposure still controlled by the-p/port choice at run time; container users who want local-only exposure should publish with-p 127.0.0.1:8000:8000instead of-p 8000:8000(which binds all host interfaces) - No CORS - no cross-origin access is allowed, not even a wildcard
- Cross-site request defenses - DNS-name
Hostheaders other than localhost are rejected unless allowlisted via theALLOWED_HOSTSenvironment variable (IP literals always work; exact names,*.suffixwildcards, or*to opt out), blocking DNS rebinding; POSTs with a cross-siteOriginorSec-Fetch-Siteheader are rejected; and JSON endpoints requireContent-Type: application/json, which browsers cannot send cross-site without a CORS preflight - together blocking CSRF against the local instance - Strict Content Security Policy -
script-src 'self'with no inline-script carve-out (all handlers are wired via delegated listeners; the theme bootstrap is an external file), so injected markup renders as inert text instead of executing; the policy'sreport-urilogs any violation server-side via/api/csp-report - Bundled CyberChef - the one exception to that policy: the built-in CyberChef at
/cyberchef/gets its own, looser one (it needseval, WebAssembly andblob:workers to run), applied to CyberChef's own responses only, never to SO-CRATES's pages. CyberChef shares SO-CRATES's origin, so the image ships only an unmodified official release, pinned by version and SHA-256 checksum - Input validation - on all endpoints (IP, port, MD5, path traversal)
- File-type routing - PCAPs, log files, email messages, and everything else each only ever reach their own analyzer (Suricata, Zircolite/Sigma, the email parser + YARA, YARA)
- SSRF protection - on "Load from URL", including a DNS-rebinding-safe resolve-then-connect
- Extracted files - files Suricata carved from traffic, and an email's message and attachments, are served only by exact SHA256 from that analysis's own
filestore/(no client-supplied path, symlinks out of it refused), asapplication/octet-streamdownloads a browser never renders, capped at 25 MB - Zip safety - zip-slip and zip-bomb (decompressed-size) protection on archive extraction
- Upload limits - a hard size ceiling plus an upfront disk-space check before accepting an upload
- Generic error messages - no internal details or stack traces leaked
- Content-Security-Policy - sent on every response, along with
X-Frame-Options: DENYandX-Content-Type-Options: nosniff - Only GET and POST -
HEADrequests are refused, since the web server's built-in HEAD handling bypassed the app's own request checks - Non-root container - the Docker/Podman image runs as a non-root user
- No startup network calls - rule refresh is always an explicit, on-demand action from the Rules modal, never automatic