Back
security audit
APR 8

Security Audit β€” April 2026

Results from our internal security audit: zero critical findings, all issues resolved.

πŸ‘€
Postbox Team
Β· Β· 3 min read

We run periodic internal security audits to verify that Postbox meets the standard we set for ourselves. This is a summary of our April 2026 audit.

Scope

The audit covered the full application stack:

  • Authentication β€” session management, API keys, OAuth 2.1, two-factor
  • Authorization β€” scope enforcement, entitlement checks, admin access
  • Input validation β€” submission schemas, parameter handling, form data
  • Injection vectors β€” SQL, XSS, SSRF, command injection
  • Network security β€” CORS, CSP, rate limiting, security headers
  • Data handling β€” tenant isolation, soft deletes, PII exposure
  • Background processing β€” Oban worker safety, idempotency
  • Dependencies β€” known vulnerabilities, outdated packages
  • Infrastructure β€” container security, TLS, secrets management

Results

Severity Found Resolved
Critical 0 β€”
High 2 2
Medium 5 5
Low 5 4
Info 9 β€”

Zero critical findings. All high and medium issues were resolved in the same session as the audit.

What we found and fixed

SSRF protection at delivery time

Webhook destinations are validated when created, but DNS can change between save and delivery. We added DNS pinning β€” the webhook delivery system now resolves the hostname, validates the IP is not in a private range, and connects directly to the validated IP. This closes the window for DNS rebinding attacks targeting internal services.

Session hardening

Session cookies now enforce a server-side max_age, preventing indefinite session replay in browsers that restore session cookies after restart.

Cache bounds

Our endpoint cache β€” used for fast submission validation β€” now has a TTL and a maximum entry count to prevent unbounded memory growth.

Input sanitization

Blog post code fence languages are now sanitized to prevent injection through markdown content. Webhook destinations block http://localhost in production.

Security headers

Added Referrer-Policy: strict-origin-when-cross-origin to prevent token leakage in referrer headers. Tightened img-src CSP to remove the https: wildcard. CSP form-action is now environment-specific.

Rate limiting

The rate limiter now reads the correct client IP from the X-Forwarded-For chain, preventing IP spoofing to bypass rate limits.

What was already solid

The audit confirmed several areas where the existing architecture is strong:

  • Zero SQL injection vectors β€” all queries use parameterized inputs
  • No atom exhaustion risk β€” no String.to_atom on user input
  • OAuth 2.1 with PKCE β€” MCP authentication follows the spec
  • Database TLS β€” production uses verify_peer with certificate pinning
  • HMAC verification β€” webhook signatures use timing-safe comparison
  • Worker idempotency β€” background jobs handle retries safely
  • CSRF protection β€” enabled on all browser routes

Tools used

  • Manual code review of authentication, authorization, and data paths
  • Sobelow β€” Phoenix security scanner
  • Credo β€” static analysis (strict mode)
  • Dialyzer β€” type checking
  • mix deps.audit β€” dependency vulnerability scanning

What’s next

  • Third-party penetration testing
  • SOC 2 Type II preparation
  • Automated security regression tests for resolved findings
Have thoughts?
Or connect for more dispatches.