rwf2 / Rocket

A web framework for Rust.
https://rocket.rs
Other
24.4k stars 1.56k forks source link

Native support for Content-Security-Policy #264

Open BernhardPosselt opened 7 years ago

BernhardPosselt commented 7 years ago

Similar to https://github.com/SergioBenitez/Rocket/issues/25 there should be an easy way to configure a CSP. CSP is a way to make XSS almost impossible and is easy and straight forward to configure.

I'm using both CORS and CSP in a Django project and every time a new Django version is released, it's a huge pain to wait for all the necessary extensions to support the current version. In addition to that adding CSP should be pretty straight forward:

It should be possible to define different CSP policies for different routes (e.g. register user pages may want to include RECaptcha which needs certain CSP exemptions)

Reasons to not include CSP for me would be:

Reasons to include a CSP implementation in Rocket for me would be:

jrozner commented 7 years ago

This is something that I've spent some time thinking about because we offer functionality like it in one of our products. Currently the way that we handle it is by forcing the user to enter the fully created string and it's just added to all responses. As you're probably thinking, this is a really bad way to do it. Generating CSP headers can be extremely difficult if your application is complex and pull resources for many places and it's incredibly easy to screw up. Something we've talked about doing a creating a GUI tool for configuring it and ideally putting it into a format that the tool can read and then generate a string or create a serializer that goes both ways. One other thing to keep in mind is that it's probably a good idea to store a cached version of the generated header once it's been generated once since this will be added to all responses leaving the server and computing it each time could be expensive.

fabricedesre commented 7 years ago

There is a pretty good documentation at https://wiki.mozilla.org/Security/Guidelines/Web_Security#Content_Security_Policy including some candidates for default CSPs. From an implementation point of view, it looks like a Fairing could be used to attach CSPs to paths. I agree with everything about the difficulty to create and manage good CSPs ;)

omac777 commented 3 years ago

Hi there,

I took out rocket.rs for a trial run this weekend:

Then I let ssllabs and webpagetest have a go at https://davidmarceau.tk

https://www.ssllabs.com/ssltest/analyze.html?d=davidmarceau.tk

https://www.webpagetest.org/result/210412_AiDcGM_8314e8be0968b1d3f888f9aa862e7391/

I didn't get A+ on ssllabs because content security policy(csp) is missing.

In the webpagetest security score, if you click on it, it says: " Missing Content Security Policy. A computer security standard introduced to prevent cross-site scripting (XSS), clickjacking and other code injection attacks resulting from execution of malicious content in the trusted web page context."

As a user taking out golang-based caddy for a test run, I can achieve A+ from ssllabs in no time flat, but I would have enjoyed being able to use helmet csp defaults to achieve the same thing with rocket.rs. I really think the proposed helmet csp would have been preferrable to no csp. It would help rocket.rs reach better security scores on ssllabs/webpagetest and attain even more popularity for rocket.rs' ease of use. I do hope you'll reconsider.

Also I tried unsuccessfully to use: https://securitytxt.org/ By making available as static files:

$ cat security-policy.txt Content-Security-Policy: default-src https: Content-Security-Policy: default-src *; object-src 'none' Content-Security-Policy: default-src 'self'; img-src 'self' object-src 'none' Content-Security-Policy: default-src 'none'; font-src 'self'; img-src 'self'; object-src 'none'; script-src 'self'; style-src 'self' Content-Security-Policy: default-src https: 'unsafe-eval' 'unsafe-inline'; object-src 'none'


Get a free domain name from freenom
https://my.freenom.com

Get a free ssl cert from zerossl.com
https://app.zerossl.com/

zerosslCerts11April2021/ca_bundle.crt zerosslCerts11April2021/certificate.crt zerosslCerts11April2021/private.key cat zerosslCerts11April2021/certificate.crt zerosslCerts11April2021/ca_bundle.crt > zerosslCerts11April2021/rocketrsFullChain11April2021.crt


Then tweak the Rocket.toml to point to that private.key and full chain:

$ cat Rocket.toml [global.tls] certs = "zerosslCerts11April2021/rocketrsFullChain11April2021.crt" key = "zerosslCerts11April2021/private.key"

cat Cargo.toml [package] name = "davidmarceau_tk_static" version = "0.0.0" workspace = "../../" publish = false

[dependencies] rocket = { path = "../../core/lib", features = ["tls"] } rocket_contrib = { path = "../../contrib/lib", features = ["helmet"] }

cat main.rs extern crate rocket; extern crate rocket_contrib;

[cfg(test)] mod tests;

use rocket::http::uri::Uri; use rocket_contrib::helmet::SpaceHelmet; use rocket_contrib::helmet::Frame; use rocket_contrib::helmet::XssFilter; use rocket_contrib::helmet::Hsts; use rocket_contrib::serve::StaticFiles;

fn rocket() -> rocket::Rocket { let site_uri = Uri::parse("https://davidmarceau.tk").unwrap(); rocket::ignite().attach( rocket_contrib::helmet::SpaceHelmet::default() .enable(Hsts::default()) .enable(XssFilter::Enable) .enable(Frame::AllowFrom(site_uri)) ).mount("/", StaticFiles::from("static")) }

fn main() { rocket().launch(); }



I hope the above helps other get an A for a security score at least, but yes if you could add that helmet csp, we could all get A+ security scores :)

Thank you for listening.