kanidmd_core/https/middleware/security_headers.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
use axum::{
body::Body,
extract::State,
http::{header, HeaderValue, Request},
middleware::Next,
response::Response,
};
use crate::https::ServerState;
const PERMISSIONS_POLICY_VALUE: &str = "fullscreen=(), geolocation=()";
const X_CONTENT_TYPE_OPTIONS_VALUE: &str = "nosniff";
pub async fn security_headers_layer(
State(state): State<ServerState>,
request: Request<Body>,
next: Next,
) -> Response {
// wait for the middleware to come back
let mut response = next.run(request).await;
// add the Content-Security-Policy header, which defines how contact will be accessed/run based on the source URL
let headers = response.headers_mut();
headers.insert(header::CONTENT_SECURITY_POLICY, state.csp_header);
// X-Content-Type-Options tells the browser if it's OK to "sniff" or guess the content type of a response
//
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
// https://scotthelme.co.uk/hardening-your-http-response-headers/#x-content-type-options
headers.insert(
header::X_CONTENT_TYPE_OPTIONS,
HeaderValue::from_static(X_CONTENT_TYPE_OPTIONS_VALUE),
);
// Permissions policy defines access to platform services like geolocation, fullscreen etc.
//
// https://www.w3.org/TR/permissions-policy-1/
headers.insert(
"Permissions-Policy",
HeaderValue::from_static(PERMISSIONS_POLICY_VALUE),
);
// Don't send a referrer header when the user is navigating to a non-HTTPS URL
// Ref:
// https://scotthelme.co.uk/a-new-security-header-referrer-policy/
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
headers.insert(
header::REFERRER_POLICY,
HeaderValue::from_static("no-referrer-when-downgrade"),
);
response
}