From 7893df38f4cca1f6690b483547e1187a5a8f6111 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Fri, 16 Oct 2020 11:41:26 +0500 Subject: [PATCH] Implement CSRF protection fairing --- Cargo.lock | 8 ++++++++ Cargo.toml | 2 ++ src/csrf.rs | 14 +++++++++++--- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f74731e..6454c29 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,6 +97,12 @@ version = "0.12.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" +[[package]] +name = "base64" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" + [[package]] name = "bcrypt" version = "0.8.2" @@ -299,10 +305,12 @@ checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed" name = "fedihub-registry" version = "0.0.0" dependencies = [ + "base64 0.13.0", "bcrypt", "diesel", "dotenv", "r2d2", + "rand", "regex", "rocket", "rocket_contrib", diff --git a/Cargo.toml b/Cargo.toml index baf47e9..2831453 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,9 +13,11 @@ categories = [] publish = true [dependencies] +base64 = "0.13.0" bcrypt = "0.8.2" dotenv = "0.15.0" r2d2 = "0.8.9" +rand = "0.7.3" regex = "1.4.1" serde = "1.0" serde_derive = "1.0" diff --git a/src/csrf.rs b/src/csrf.rs index 34d2d43..a32b652 100644 --- a/src/csrf.rs +++ b/src/csrf.rs @@ -1,7 +1,10 @@ +use rand::RngCore; use rocket::{Data, Request}; use rocket::fairing::{Fairing as RocketFairing, Info, Kind}; +use rocket::http::Cookie; const COOKIE_NAME: &str = "csrf_token"; +const RAW_TOKEN_LENGTH: usize = 32; pub struct Fairing; @@ -20,8 +23,13 @@ impl RocketFairing for Fairing { } fn on_request(&self, request: &mut Request, _: &Data) { - let _token: Option = request.cookies() - .get_private(COOKIE_NAME) - .and_then(|cookie| Some(cookie.value().to_string())); + if request.cookies().get_private(COOKIE_NAME).is_some() { return }; + + let mut raw = [0u8; RAW_TOKEN_LENGTH]; + rand::thread_rng().fill_bytes(&mut raw); + + let encoded = base64::encode(raw); + + request.cookies().add_private(Cookie::new(COOKIE_NAME, encoded)); } }