Skip to content

Commit b54b638

Browse files
sgrifcarols10cents
authored andcommitted
Add security headers
These headers are all pretty straightforward except CSP. For CSP I defined the sources based on what was loaded from visiting the main page and all crates. Images should be safe, so I've allowed them from all sources. This should be checked on staging before deploying. Fixes rust-lang#586.
1 parent 6ecbccd commit b54b638

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

src/http.rs

+38-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
use conduit::{Request, Response};
2+
use conduit_middleware::Middleware;
13
use curl;
24
use curl::easy::{Easy, List};
35
use oauth2::*;
@@ -6,7 +8,7 @@ use util::{CargoResult, internal, ChainError, human};
68
use serde_json;
79
use serde::Deserialize;
810
use std::str;
9-
11+
use std::error::Error;
1012

1113
/// Does all the nonsense for sending a GET to Github. Doesn't handle parsing
1214
/// because custom error-code handling may be desirable. Use
@@ -88,3 +90,38 @@ pub fn token(token: String) -> Token {
8890
token_type: String::new(),
8991
}
9092
}
93+
94+
pub struct SecurityHeadersMiddleware;
95+
96+
impl Middleware for SecurityHeadersMiddleware {
97+
fn after(&self, _: &mut Request, mut res: Result<Response, Box<Error+Send>>)
98+
-> Result<Response, Box<Error+Send>> {
99+
if let Ok(ref mut response) = res {
100+
response.headers.insert(
101+
"Content-Security-Policy".into(),
102+
vec!["default-src 'self'; \
103+
script-src 'self' https://www.google-analytics.com https://www.google.com; \
104+
style-src 'self' https://www.google.com; \
105+
img-src *; \
106+
object-src 'none'".into()],
107+
);
108+
response.headers.insert(
109+
"X-Content-Type-Options".into(),
110+
vec!["nosniff".into()],
111+
);
112+
response.headers.insert(
113+
"X-Frame-Options".into(),
114+
vec!["SAMEORIGIN".into()],
115+
);
116+
response.headers.insert(
117+
"X-XSS-Protection".into(),
118+
vec!["1; mode=block".into()],
119+
);
120+
response.headers.insert(
121+
"Strict-Transport-Security".into(),
122+
vec!["max-age=31536000; includeSubDomains".into()],
123+
);
124+
}
125+
res
126+
}
127+
}

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
227227
cookie::Key::from_master(app.session_key.as_bytes()),
228228
env == Env::Production,
229229
));
230+
if env == Env::Production {
231+
m.add(http::SecurityHeadersMiddleware);
232+
}
230233
m.add(app::AppMiddleware::new(app));
231234

232235
// Run each request in a transaction and roll back the transaction if the request results

0 commit comments

Comments
 (0)