CSRF (Cross-Site Request Forgery) protection for Rocket web framework https://crates.io/crates/rocket_csrf
Go to file
Alex Kotov 58cebbac0b
Fix README.md
2022-07-13 07:52:44 +03:00
examples/minimal Fix example 2022-07-13 07:37:42 +03:00
src Update for 2nd release candidate 2022-05-17 07:00:52 +00:00
tests Update for 2nd release candidate 2022-05-17 07:00:52 +00:00
.gitignore Add existing code 2020-10-17 02:41:07 +05:00
Cargo.toml Do not bump version 2022-07-13 07:38:50 +03:00
LICENSE Add LICENSE 2020-10-17 02:47:32 +05:00
README.md Fix README.md 2022-07-13 07:52:44 +03:00

README.md

rocket_csrf

CSRF (Cross-Site Request Forgery) protection for Rocket web framework.

WARNING! The implementation is very simple for now and may not be ready for production.

Discussion about CSRF protection in Rocket is here.

Table of contents

Usage

Attach fairing to the Rocket instance:

#![feature(decl_macro)]

#[macro_use] extern crate rocket;
#[macro_use] extern crate serde_derive;

use rocket_dyn_templates::Template;

#[launch]
fn rocket() -> _ {
    rocket::ignite()
        .attach(rocket_csrf::Fairing::default())
        .attach(Template::fairing())
        .mount("/", routes![new, create])
}

You also can configure fairing:

#[launch]
fn rocket() -> _ {
    rocket::ignite()
        .attach(rocket_csrf::Fairing::new(
            rocket_csrf::CsrfConfig::default()
                .with_cookie_name("foobar")
                .with_cookie_len(64)
                .with_lifetime(time::Duration::days(3)),
        ))
        .attach(Template::fairing())
        .mount("/", routes![new, create])
}

Add guard to any request where you want to have access to session's CSRF token (e.g. to include it in forms) or verify it (e.g. to validate form):

use rocket::form::Form;
use rocket::response::Redirect;
use rocket_csrf::CsrfToken;
use rocket_dyn_templates::Template;

#[get("/comments/new")]
fn new(csrf_token: CsrfToken) -> Template {
    // your code
}

#[post("/comments", data = "<form>")]
fn create(csrf_token: CsrfToken, form: Form<Comment>) -> Redirect {
    // your code
}

Get CSRF token from guard to use it in templates:

#[get("/comments/new")]
fn new(csrf_token: CsrfToken) -> Template {
    let authenticity_token: &str = csrf_token.authenticity_token();

    // your code
}

Add CSRF token to your HTML forms in templates:

<form method="post" action="/comments">
    <input type="hidden" name="authenticity_token" value="{{ authenticity_token }}"/>
    <!-- your fields -->
</form>

Add attribute authenticity_token to your forms:

#[derive(FromForm)]
struct Comment {
    authenticity_token: String,
    // your attributes
}

Validate forms to have valid authenticity token:

#[post("/comments", data = "<form>")]
fn create(csrf_token: CsrfToken, form: Form<Comment>) -> Redirect {
    if let Err(_) = csrf_token.verify(&form.authenticity_token) {
        return Redirect::to(uri!(new));
    }

    // your code
}

See the complete code in minimal example.

TODO

  • Add fairing to verify all requests as an option.
  • Add data guard to verify forms with a guard.
  • Add helpers to render form field.
  • Add helpers to add HTML meta tags for Ajax with X-CSRF-Token header.
  • Verify X-CSRF-Token header.
  • Use authenticity token encryption from Ruby on Rails.
  • Allow to configure CSRF protection (CSRF token byte length, cookie name, etc.).
  • Set cookie to expire with session.