Hardening checklist

PDF Server ships no built-in security controls by design — these are the controls you add around it.

Work through this before exposing PDF Server. Items are grouped by what they defend against; see Proved issues for the underlying findings.

Network & access

  • Put an authenticating reverse proxy in front of the service (no route has built-in auth).
  • Enforce a request body-size limit at the proxy.
  • Enforce read/write/idle timeouts at the proxy.
  • Add rate limiting at the proxy.
  • Do not expose the port directly to untrusted networks.

Egress (defends SSRF)

  • Apply an egress network policy that blocks:
    • link-local 169.254.0.0/16 (cloud metadata 169.254.169.254),
    • private ranges 10/8, 172.16/12, 192.168/16,
    • anything the container does not legitimately need.
  • If you use remote templates, build their requests only from trusted data, and allowlist the target hosts.

Browser sandbox (compensates for --no-sandbox)

  • Run the container with a restrictive seccomp profile.
  • Prefer user-namespace isolation or a stronger sandbox (gVisor).
  • Run as non-root (the image already does).
  • Set CPU and memory limits.

Template & data hygiene (defends XSS-into-PDF)

  • Never pass untrusted data to raw-HTML sinks: {{{triple}}}, the markdown helper, or embed_text.
  • Sanitize untrusted Markdown before rendering it.
  • Validate untrusted data with a schema.json; for compositions, validate at the composition boundary (child schemas are not re-validated).
  • Avoid placing untrusted data directly into src/href/URL positions; validate/allowlist if you must.

Availability

  • Raise RENDER_POOL_MAX_TOTAL above the default of 1 for real load.
  • Bound total per-request time at the proxy.
  • Monitor /_metadata for liveness (cheap) and /_status for pool health.

Data exposure

  • Treat document/asset contents on the internal render server as visible to the rendering page; do not ship secrets in assets/.