1use crate::{SecurityError, SecurityScanner, evaluate, request_parts};
3use http::Request;
4use std::future::Future;
5use std::pin::Pin;
6use std::sync::Arc;
7use std::task::{Context as TaskCtx, Poll};
8
9#[derive(Clone)]
12pub struct SecurityLayer {
13 scanner: Arc<SecurityScanner>,
14}
15
16impl SecurityLayer {
17 pub fn new() -> Self {
18 Self {
19 scanner: Arc::new(SecurityScanner::new()),
20 }
21 }
22}
23
24impl Default for SecurityLayer {
25 fn default() -> Self {
26 Self::new()
27 }
28}
29
30impl<S> tower::Layer<S> for SecurityLayer {
31 type Service = SecurityService<S>;
32
33 fn layer(&self, inner: S) -> Self::Service {
34 SecurityService {
35 inner,
36 scanner: Arc::clone(&self.scanner),
37 }
38 }
39}
40
41#[derive(Clone)]
42pub struct SecurityService<S> {
43 inner: S,
44 scanner: Arc<SecurityScanner>,
45}
46
47impl<S, B> tower::Service<Request<B>> for SecurityService<S>
48where
49 S: tower::Service<Request<B>> + Send + 'static,
50 S::Future: Send + 'static,
51 S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
52 S::Response: From<axum::response::Response> + Send,
55 B: Send + 'static,
56{
57 type Response = S::Response;
58 type Error = SecurityError;
59 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
60
61 fn poll_ready(&mut self, cx: &mut TaskCtx<'_>) -> Poll<Result<(), Self::Error>> {
62 self.inner
63 .poll_ready(cx)
64 .map_err(|e| SecurityError::Inner(e.into()))
65 }
66
67 fn call(&mut self, req: Request<B>) -> Self::Future {
68 let scanner = Arc::clone(&self.scanner);
69 let parts = request_parts(&req);
70 let strings: Vec<&str> = parts.iter().map(|s| s.as_str()).collect();
71 let results = scanner.scan_parts(&strings);
72
73 if let Some(err) = evaluate(&results) {
74 use axum::response::IntoResponse;
75 let resp: S::Response = err.into_response().into();
76 return Box::pin(async move { Ok(resp) });
77 }
78
79 let fut = self.inner.call(req);
80 Box::pin(async move { fut.await.map_err(|e| SecurityError::Inner(e.into())) })
81 }
82}
83
84#[derive(Clone)]
93pub struct SecurityBodyLayer {
94 scanner: Arc<SecurityScanner>,
95 body_limit: usize,
96}
97
98impl SecurityBodyLayer {
99 pub fn new() -> Self {
100 Self {
101 scanner: Arc::new(SecurityScanner::new()),
102 body_limit: 10 * 1024 * 1024,
103 }
104 }
105
106 pub fn body_limit(mut self, limit: usize) -> Self {
110 self.body_limit = limit;
111 self
112 }
113}
114
115impl Default for SecurityBodyLayer {
116 fn default() -> Self {
117 Self::new()
118 }
119}
120
121impl<S> tower::Layer<S> for SecurityBodyLayer {
122 type Service = SecurityBodyService<S>;
123
124 fn layer(&self, inner: S) -> Self::Service {
125 SecurityBodyService {
126 inner,
127 scanner: Arc::clone(&self.scanner),
128 body_limit: self.body_limit,
129 }
130 }
131}
132
133#[derive(Clone)]
134pub struct SecurityBodyService<S> {
135 inner: S,
136 scanner: Arc<SecurityScanner>,
137 body_limit: usize,
138}
139
140impl<S> tower::Service<Request<axum::body::Body>> for SecurityBodyService<S>
141where
142 S: tower::Service<Request<axum::body::Body>> + Clone + Send + 'static,
143 S::Future: Send + 'static,
144 S::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
145{
146 type Response = S::Response;
147 type Error = SecurityError;
148 type Future = Pin<Box<dyn Future<Output = Result<Self::Response, Self::Error>> + Send>>;
149
150 fn poll_ready(&mut self, cx: &mut TaskCtx<'_>) -> Poll<Result<(), Self::Error>> {
151 self.inner
152 .poll_ready(cx)
153 .map_err(|e| SecurityError::Inner(e.into()))
154 }
155
156 fn call(&mut self, req: Request<axum::body::Body>) -> Self::Future {
157 let scanner = Arc::clone(&self.scanner);
158 let body_limit = self.body_limit;
159 let mut inner = self.inner.clone();
160 let parts = request_parts(&req);
161 let strings: Vec<&str> = parts.iter().map(|s| s.as_str()).collect();
162 let header_results = scanner.scan_parts(&strings);
163
164 Box::pin(async move {
165 let (parts, body) = req.into_parts();
166 let bytes = match axum::body::to_bytes(body, body_limit).await {
169 Ok(bytes) => bytes,
170 Err(e) => {
171 let inner: Box<dyn std::error::Error + Send + Sync> = e.into_inner();
173 if inner
174 .downcast_ref::<http_body_util::LengthLimitError>()
175 .is_some()
176 {
177 return Err(SecurityError::BodyTooLarge);
178 }
179 return Err(SecurityError::Inner(inner));
180 }
181 };
182
183 let mut results = header_results;
184 results.extend(scanner.scan_body(&bytes));
185
186 if let Some(err) = evaluate(&results) {
187 return Err(err);
188 }
189
190 let req = Request::from_parts(parts, axum::body::Body::from(bytes));
191 inner
192 .call(req)
193 .await
194 .map_err(|e| SecurityError::Inner(e.into()))
195 })
196 }
197}