diff --git a/app/styles/app.scss b/app/styles/app.scss index 9d3ab9d98ad..85186a67ed6 100644 --- a/app/styles/app.scss +++ b/app/styles/app.scss @@ -342,3 +342,11 @@ h1 { padding: 5px; } } + +.arrow-in-list svg { + background: #fff; +} + +a.arrow svg { + background: #EEECDD; +} diff --git a/app/templates/components/category-list.hbs b/app/templates/components/category-list.hbs index 155503f7045..172406d6ce4 100644 --- a/app/templates/components/category-list.hbs +++ b/app/templates/components/category-list.hbs @@ -3,7 +3,9 @@
  • {{#link-to 'category' category.slug class='name'}} {{ category.category }} ({{ format-num category.crates_cnt }}) - {{svg-jar "right-arrow"}} +
    + {{svg-jar "right-arrow"}} +
    {{/link-to}}
  • {{/each}} diff --git a/app/templates/components/crate-list.hbs b/app/templates/components/crate-list.hbs index 1663f04c4a9..dd0cebdd7fa 100644 --- a/app/templates/components/crate-list.hbs +++ b/app/templates/components/crate-list.hbs @@ -3,7 +3,9 @@
  • {{#link-to 'crate' crate.id class='name'}} {{ crate.name }} ({{ crate.max_version }}) - {{svg-jar "right-arrow"}} +
    + {{svg-jar "right-arrow"}} +
    {{/link-to}}
  • {{/each}} diff --git a/app/templates/components/keyword-list.hbs b/app/templates/components/keyword-list.hbs index 3f410e9e9b9..171350fb160 100644 --- a/app/templates/components/keyword-list.hbs +++ b/app/templates/components/keyword-list.hbs @@ -3,7 +3,9 @@
  • {{#link-to 'keyword' keyword class='name'}} {{ keyword.id }} ({{ format-num keyword.crates_cnt }}) - {{svg-jar "right-arrow"}} +
    + {{svg-jar "right-arrow"}} +
    {{/link-to}}
  • {{/each}} diff --git a/app/templates/crate/version.hbs b/app/templates/crate/version.hbs index 9cc4528b7f9..f3dcc984911 100644 --- a/app/templates/crate/version.hbs +++ b/app/templates/crate/version.hbs @@ -40,9 +40,6 @@ -{{! This is used to set the url of to actually download a file }} - - {{#if currentVersion.yanked}}
    diff --git a/app/templates/crate/versions.hbs b/app/templates/crate/versions.hbs index 352246808b1..1873d57b651 100644 --- a/app/templates/crate/versions.hbs +++ b/app/templates/crate/versions.hbs @@ -22,7 +22,7 @@ {{/if}}
    {{#link-to 'crate.version' version.num class='arrow'}} - {{svg-jar "right-arrow" style="background-color: #EEECDD"}} + {{svg-jar "right-arrow"}} {{/link-to}}
    {{/each}} diff --git a/public/assets/right-arrow.svg b/public/assets/right-arrow.svg index 322066f086e..f44739eb1ff 100644 --- a/public/assets/right-arrow.svg +++ b/public/assets/right-arrow.svg @@ -1,4 +1,4 @@ - + diff --git a/src/http.rs b/src/http.rs index 9d8714ecddd..552bca78913 100644 --- a/src/http.rs +++ b/src/http.rs @@ -1,3 +1,5 @@ +use conduit::{Request, Response}; +use conduit_middleware::Middleware; use curl; use curl::easy::{Easy, List}; use oauth2::*; @@ -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 @@ -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>, + ) -> Result> { + 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; \ + 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 + } +} diff --git a/src/lib.rs b/src/lib.rs index ff6ef9b471b..f9b462b0d76 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -227,6 +227,9 @@ pub fn middleware(app: Arc) -> 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