Security

Everything in an event is untrusted: it came from your users’ browsers and requests. OpenFault scrubs it before storing it and fences it on the way out.

Scrubbing on ingest

Before anything is written:

Raw payloads are never logged.

What is stored

In /data/openfault.db (SQLite):

Output

In the REST API, MCP and live stream, event strings are control-character stripped and length-capped. In MCP they sit inside a fenced block marked as untrusted, with fence markers in the data broken up so it cannot escape the block. Event detail (frames, breadcrumbs, request) is withheld from tokens until a person approves the issue for fixing. The web UI autoescapes everything.

SSRF

OpenFault makes outbound requests only for webhooks, email and the push relay. It never fetches source maps from URLs.

Webhooks:

OPENFAULT_ALLOW_PRIVATE_WEBHOOKS=1 lifts the address rules (and allows plain http:// to loopback). Note: an HTTP(S)_PROXY variable bypasses the DNS check, since the proxy resolves the host.

Rate limits

Behind a proxy, set OPENFAULT_TRUST_PROXY=1 so the limits see the client’s IP from X-Forwarded-For. Do not set it without a proxy that overwrites that header.

Sessions

Session cookies are HttpOnly and SameSite=Lax, and Secure when OPENFAULT_BASE_URL is https://. Sessions last 30 days and are revocable. Cookie-authenticated writes have a cross-site request check.

Reporting a vulnerability

Please do not open a public issue. Open a private security advisory on GitHub with the details and steps to reproduce. We will reply there.