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

string

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

string

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

response HttpResponse

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

response HttpResponse

The response being written.

nonce string

The nonce placed on this page's script tags.

policyFormat string

An 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

string

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.