Skip to content

Add security headers #597

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Aug 12, 2017
8 changes: 8 additions & 0 deletions app/styles/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -342,3 +342,11 @@ h1 {
padding: 5px;
}
}

.arrow-in-list svg {
background: #fff;
}

a.arrow svg {
background: #EEECDD;
}
4 changes: 3 additions & 1 deletion app/templates/components/category-list.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<li>
{{#link-to 'category' category.slug class='name'}}
<span>{{ category.category }} ({{ format-num category.crates_cnt }})</span>
{{svg-jar "right-arrow"}}
<div class='arrow-in-list'>
{{svg-jar "right-arrow"}}
</div>
{{/link-to}}
</li>
{{/each}}
Expand Down
4 changes: 3 additions & 1 deletion app/templates/components/crate-list.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<li>
{{#link-to 'crate' crate.id class='name'}}
<span>{{ crate.name }} ({{ crate.max_version }})</span>
{{svg-jar "right-arrow"}}
<div class='arrow-in-list'>
{{svg-jar "right-arrow"}}
</div>
{{/link-to}}
</li>
{{/each}}
Expand Down
4 changes: 3 additions & 1 deletion app/templates/components/keyword-list.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
<li>
{{#link-to 'keyword' keyword class='name'}}
<span>{{ keyword.id }} ({{ format-num keyword.crates_cnt }})</span>
{{svg-jar "right-arrow"}}
<div class='arrow-in-list'>
{{svg-jar "right-arrow"}}
</div>
{{/link-to}}
</li>
{{/each}}
Expand Down
3 changes: 0 additions & 3 deletions app/templates/crate/version.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,6 @@
</div>
</div>

{{! This is used to set the url of to actually download a file }}
<iframe id='download-frame' style='display:none'></iframe>

{{#if currentVersion.yanked}}
<div class='crate-info'>
<div>
Expand Down
2 changes: 1 addition & 1 deletion app/templates/crate/versions.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
{{/if}}
</div>
{{#link-to 'crate.version' version.num class='arrow'}}
{{svg-jar "right-arrow" style="background-color: #EEECDD"}}
{{svg-jar "right-arrow"}}
{{/link-to}}
</div>
{{/each}}
Expand Down
2 changes: 1 addition & 1 deletion public/assets/right-arrow.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 48 additions & 1 deletion src/http.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use conduit::{Request, Response};
use conduit_middleware::Middleware;
use curl;
use curl::easy::{Easy, List};
use oauth2::*;
Expand All @@ -6,7 +8,7 @@ use util::{CargoResult, internal, ChainError, human};
use serde_json;
use serde::Deserialize;
use std::str;

use std::error::Error;

/// Does all the nonsense for sending a GET to Github. Doesn't handle parsing
/// because custom error-code handling may be desirable. Use
Expand Down Expand Up @@ -88,3 +90,48 @@ pub fn token(token: String) -> Token {
token_type: String::new(),
}
}

#[derive(Clone, Copy, Debug)]
pub struct SecurityHeadersMiddleware;

impl Middleware for SecurityHeadersMiddleware {
fn after(
&self,
_: &mut Request,
mut res: Result<Response, Box<Error + Send>>,
) -> Result<Response, Box<Error + Send>> {
if let Ok(ref mut response) = res {
// It would be better if we didn't have to have 'unsafe-eval' in the `script-src`
// policy, but google charts (used for the download graph on crate pages) uses `eval`
// to load scripts. Remove 'unsafe-eval' if google fixes the issue:
// https://github.com/google/google-visualization-issues/issues/1356
// or if we switch to a different graph generation library.
response.headers.insert(
"Content-Security-Policy".into(),
vec![
"default-src 'self'; \
connect-src 'self' https://docs.rs; \
script-src 'self' 'unsafe-eval' \
https://www.google-analytics.com https://www.google.com; \
Comment on lines +114 to +115
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Upstream issue seems fixed, is this still needed?

style-src 'self' https://www.google.com https://ajax.googleapis.com; \
img-src *; \
object-src 'none'"
.into(),
],
);
response.headers.insert(
"X-Content-Type-Options".into(),
vec!["nosniff".into()],
);
response.headers.insert(
"X-Frame-Options".into(),
vec!["SAMEORIGIN".into()],
);
response.headers.insert(
"X-XSS-Protection".into(),
vec!["1; mode=block".into()],
);
}
res
}
}
3 changes: 3 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,9 @@ pub fn middleware(app: Arc<App>) -> MiddlewareBuilder {
cookie::Key::from_master(app.session_key.as_bytes()),
env == Env::Production,
));
if env == Env::Production {
m.add(http::SecurityHeadersMiddleware);
}
m.add(app::AppMiddleware::new(app));

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