Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 013eb66

Browse files
committedMar 6, 2017
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 #586.
1 parent 4074d59 commit 013eb66

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed
 

‎src/http.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use conduit::{Request, Response};
2+
use conduit_middleware::Middleware;
13
use curl;
24
use curl::easy::{Easy, List};
35
use oauth2::*;
46
use app::App;
57
use util::{CargoResult, internal, ChainError, human};
68
use rustc_serialize::{json, Decodable};
79
use std::str;
8-
10+
use std::error::Error;
911

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

‎src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,9 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
150150
m.add(conduit_cookie::Middleware::new(app.session_key.as_bytes()));
151151
m.add(conduit_cookie::SessionMiddleware::new("cargo_session",
152152
env == Env::Production));
153+
if env == Env::Production {
154+
m.add(http::SecurityHeadersMiddleware);
155+
}
153156
m.add(app::AppMiddleware::new(app));
154157
if env != Env::Test {
155158
m.add(db::TransactionMiddleware);

0 commit comments

Comments
 (0)
Please sign in to comment.