use axum::extract::Request;
use axum::http::{HeaderName, HeaderValue};
use axum::middleware::Next;
const SECURITY_HEADERS: &[(&str, &str)] = &[
("x-content-type-options", "nosniff"),
("x-frame-options", "DENY"),
("referrer-policy", "strict-origin-when-cross-origin"),
(
"content-security-policy",
"default-src 'none'; frame-ancestors 'none'",
),
];
pub async fn security_headers_middleware(req: Request, next: Next) -> axum::response::Response {
let mut response = next.run(req).await;
let headers = response.headers_mut();
for (name, value) in SECURITY_HEADERS {
if let (Ok(n), Ok(v)) = (
HeaderName::from_bytes(name.as_bytes()),
HeaderValue::from_str(value),
) {
headers.insert(n, v);
}
}
response
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn security_headers_are_valid() {
for (name, value) in SECURITY_HEADERS {
assert!(
HeaderName::from_bytes(name.as_bytes()).is_ok(),
"invalid header name: {name}"
);
assert!(
HeaderValue::from_str(value).is_ok(),
"invalid header value: {value}"
);
}
}
}