Expand description
Per-request CSP nonce middleware — generates a fresh CSPRNG nonce
per request, makes it available via Extension<Nonce>, and
substitutes 'nonce-__RUSTANGO_NONCE__' in the CSP header so
inline <script nonce="..."> tags pass strict CSP. See
csp_nonce::CspNonceLayer.
Per-request CSP nonce middleware.
A strict Content-Security-Policy blocks inline <script> tags by
default. The standards-blessed escape hatch is per-request nonces:
the server generates a random token, drops it into the CSP header
(script-src 'nonce-XYZ'), and renders the same token onto every
inline script tag (<script nonce="XYZ">). The browser only runs
tags whose nonce matches.
§Wire-up
use rustango::csp_nonce::{CspNonceLayer, CspNonceRouterExt, Nonce};
use rustango::security_headers::{SecurityHeadersLayer, CspBuilder};
use rustango::csp_nonce::CSP_NONCE_PLACEHOLDER;
// 1. Reference the placeholder in your CSP. The middleware
// substitutes the real nonce per-request.
let csp = CspBuilder::strict_starter()
.script_src(&["'self'", CSP_NONCE_PLACEHOLDER])
.style_src(&["'self'", CSP_NONCE_PLACEHOLDER])
.build();
let app = axum::Router::new()
.route("/", axum::routing::get(home))
.security_headers(SecurityHeadersLayer::strict().csp(csp))
.csp_nonce(CspNonceLayer::default());
// 2. Read the nonce in your handler so you can render it.
async fn home(axum::Extension(nonce): axum::Extension<Nonce>) -> axum::response::Html<String> {
axum::response::Html(format!(
"<script nonce=\"{}\">console.log('hi')</script>",
nonce.value()
))
}§How substitution works
After the handler runs, the middleware looks at the response’s
content-security-policy (or content-security-policy-report-only)
header. If it contains the literal string [CSP_NONCE_PLACEHOLDER]
('nonce-__RUSTANGO_NONCE__'), the middleware replaces every
occurrence with the per-request nonce. Otherwise the header is left
untouched — non-HTML responses get their CSP exactly as configured.
Structs§
- CspNonce
Layer - CSP nonce middleware configuration.
- Nonce
- Per-request nonce. Stored in
request.extensionsby the middleware; pull it out viaaxum::Extension<Nonce>in your handler.
Constants§
- CSP_
NONCE_ PLACEHOLDER - Placeholder string that should appear in your CSP wherever you want
the per-request nonce to be substituted. Use it inside the source
list of
script-src/style-src(etc.):