Skip to main content

Module csp_nonce

Module csp_nonce 

Source
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§

CspNonceLayer
CSP nonce middleware configuration.
Nonce
Per-request nonce. Stored in request.extensions by the middleware; pull it out via axum::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.):

Traits§

CspNonceRouterExt