kanidmd_core/https/middleware/
security_headers.rs1use axum::{
2 body::Body,
3 extract::State,
4 http::{header, HeaderValue, Request},
5 middleware::Next,
6 response::Response,
7};
8
9use crate::https::ServerState;
10
11const PERMISSIONS_POLICY_VALUE: &str = "fullscreen=(), geolocation=()";
12const X_CONTENT_TYPE_OPTIONS_VALUE: &str = "nosniff";
13
14pub async fn security_headers_layer(
15 State(state): State<ServerState>,
16 request: Request<Body>,
17 next: Next,
18) -> Response {
19 let mut response = next.run(request).await;
21
22 let headers = response.headers_mut();
23
24 if !headers.contains_key(header::CONTENT_SECURITY_POLICY) {
27 headers.insert(header::CONTENT_SECURITY_POLICY, state.csp_header);
28 }
29
30 headers.insert(
35 header::X_CONTENT_TYPE_OPTIONS,
36 HeaderValue::from_static(X_CONTENT_TYPE_OPTIONS_VALUE),
37 );
38
39 headers.insert(
43 "Permissions-Policy",
44 HeaderValue::from_static(PERMISSIONS_POLICY_VALUE),
45 );
46
47 headers.insert(
52 header::REFERRER_POLICY,
53 HeaderValue::from_static("no-referrer-when-downgrade"),
54 );
55
56 response
57}
58
59pub async fn csp_header_no_form_action_layer(
60 State(state): State<ServerState>,
61 request: Request<Body>,
62 next: Next,
63) -> Response {
64 let mut response = next.run(request).await;
65
66 let headers = response.headers_mut();
67
68 headers.insert(
69 header::CONTENT_SECURITY_POLICY,
70 state.csp_header_no_form_action,
71 );
72
73 response
74}