Class BowireResponseHeaders
- Namespace
- Kuestenlogik.Bowire
- Assembly
- Kuestenlogik.Bowire.dll
The baseline headers Bowire puts on everything it serves (#625).
public static class BowireResponseHeaders
- Inheritance
-
BowireResponseHeaders
- Inherited Members
Remarks
Set on Bowire's own responses rather than through host middleware. An embedded host owns its pipeline, and a package that quietly adds headers to every response the host sends has reached outside its mount.
Fields
ApiContentSecurityPolicy
Apply the headers that apply to everything — HTML and JSON alike.
public const string ApiContentSecurityPolicy = "default-src 'none'; frame-ancestors 'none'"
Field Value
Remarks
A JSON body executes nothing, so this is not about the response's own content — it is about what happens when a browser is talked into rendering it as a document anyway. Costs nothing and closes that door.
DefaultContentSecurityPolicyFormat
The default Content-Security-Policy, with {0} for the nonce.
public const string DefaultContentSecurityPolicyFormat = "default-src 'self'; script-src 'self' 'nonce-{0}'; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https: http:; font-src 'self' data:; connect-src *; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'self'"
Field Value
Remarks
Why a nonce and not 'self'. The workbench ships its whole
JavaScript bundle inline, plus a second inline block carrying the
per-request configuration. script-src 'self' would switch the
product off. 'unsafe-inline' would silence a scanner and protect
nothing — worse than no header, because it looks solved. A nonce is the
only form that is both true and useful.
Why script-src also carries 'self'. UI extensions
are loaded by injecting a <script src> at runtime
(extensions.js), and a nonce cannot cover a tag the server never
rendered. With the nonce alone, every extension bundle was blocked —
the map widget among them — and neither the scanner nor CI could see
it, because a policy that blocks a feature still looks like a policy.
'self' permits same-origin script files, which is what
those are, and still refuses inline injection, which is the vector the
nonce is actually defending.
Why style-src carries 'unsafe-inline' and no nonce.
The DOM-building code sets inline style attributes throughout,
and a nonce does not cover style attributes. Worse, adding one would
make CSP Level 3 browsers ignore 'unsafe-inline'
entirely, so the nonce would break the layout it was meant to secure.
Why connect-src and img-src are open. The map
widget fetches basemap tiles straight from whatever tile server the
operator configured, and a tool for talking to arbitrary services has
no fixed egress list to write down. This policy buys protection
against script injection, not against egress, and saying so here is
better than a narrow value that breaks a feature on first use.
Methods
ApplyBaseline(HttpResponse)
public static void ApplyBaseline(HttpResponse response)
Parameters
responseHttpResponse
ApplyForDocument(HttpResponse, string, string?)
Apply the baseline plus the policy for a page that carries script.
public static void ApplyForDocument(HttpResponse response, string nonce, string? policyFormat = null)
Parameters
responseHttpResponseThe response being written.
noncestringThe nonce placed on this page's script tags.
policyFormatstringAn override for the policy, with
{0}for the nonce. An empty value sends no policy at all — the escape hatch for a host whose own page composes Bowire with something this default forbids. Null uses DefaultContentSecurityPolicyFormat.
NewNonce()
A fresh nonce for one response.
public static string NewNonce()
Returns
Remarks
Base64 of 16 random bytes from the OS generator. Per response, because a nonce reused across responses is a nonce an injected script can read from a cached page and replay.