Skip to content

Securityheaders extension + serve-mode startup banner#300

Open
balat wants to merge 7 commits into
masterfrom
qw4-security-headers
Open

Securityheaders extension + serve-mode startup banner#300
balat wants to merge 7 commits into
masterfrom
qw4-security-headers

Conversation

@balat

@balat balat commented Jun 26, 2026

Copy link
Copy Markdown
Member

What

Two small ease-of-use wins:

Securityheaders extension (ocsigenserver.ext.securityheaders)

Adds, with one declaration, the security headers a response should carry,
instead of hand-rolling output-filter rules:

  • X-Content-Type-Options: nosniff
  • X-Frame-Options: SAMEORIGIN
  • Strict-Transport-Security: max-age=15552000; includeSubDomains
  • Content-Security-Policy (only when configured — no safe default)

Each header can be customised or disabled (no / none / empty), and an
already-set header is left untouched. Works from the configuration file
(<securityheaders/>) and as a library (Securityheaders.run). Place it after
the extension whose responses it decorates.

Serve-mode startup banner

ocsigenserver ./public now logs Serving <dir> on http://localhost:<port>,
giving immediate feedback.

Tests

  • test/security-headers.t: the default headers and a configured CSP are
    present on responses.
  • test/serve.t: extended to assert the startup banner.

Note

Independent of #298/#299; branches from master.

balat added 7 commits June 26, 2026 13:32
ocsigenserver.ext.securityheaders adds, with a single declaration, the common
security headers a response should carry: X-Content-Type-Options: nosniff,
X-Frame-Options and Strict-Transport-Security (with sensible defaults), plus an
optional Content-Security-Policy. Each header can be customised or disabled,
and an already-set header is left untouched. Usable from the configuration file
(<securityheaders/>) and as a library (Securityheaders.run).
Serve mode now logs the directory and URL it listens on, so the user gets
immediate feedback (and tests have something to assert).
Make Strict-Transport-Security opt-in (default None) instead of on with
includeSubDomains: the extension cannot know whether the deployment is
HTTPS-only, and a default includeSubDomains can force unrelated subdomains to
HTTPS for the whole max-age. Add a safe-by-default Referrer-Policy
(strict-origin-when-cross-origin), reject CR/LF in configured header values
(response-splitting defence), and document the header roles, the HSTS/CSP
caveats and the ordering requirement.
Serve mode now loads the Securityheaders extension on demand (best-effort) and
applies the safe-by-default headers (nosniff, X-Frame-Options, Referrer-Policy)
to every response, via a new register_security_headers registry that the
extension populates when loaded.
The generated example configuration now loads the Securityheaders extension and
adds <securityheaders/> to its host, so a default install serves the
safe-by-default security headers.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant