Giter Club home page Giter Club logo

rocket_csrf's Introduction

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.

rocket_csrf's People

Contributors

fenhl avatar genusistimelord avatar kotovalexarian avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

rocket_csrf's Issues

Bug: Does not work for direct links

Currently, to use csrf tokens in a form, an additional get request has to be created to somehow redirect the user twice in order to add the CSRF guard. This is not ideal as developers have to write additional code.

To reproduce, run your minimal example, open an incognito tab, and directly go to http://127.0.0.1:8000/comments/new.

This sort of behaviour is a bug that won't be caught by 99% of developers using this library and a mitigation should be done. I believe that the csrf token generator should be separate from the token verifyer and that the guard's from_request implementation should verify the token itself instead of relying on developers to manually verify the code.

Compare the code rocket_csrf makes developers write and the code flask_wtf.csrf where all you need to do is write four lines of code and you get global post form protection.

Please add Install Instructions

After installing this crate by using

rocket_csrf = "0.3.0"

My code failed to compile. I first checked this github's cargo.toml and it was using the latest rocket. Then I ran a cargo tree and found out that 0.3.0 uses an old rocket version. Please provide installation instructions or at least update cargo!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.