Skip to content

Commit eb115a7

Browse files
authored
Merge pull request #5 from wiseaidev/csrf-header-lifespan-patch
Csrf header lifespan patch
2 parents 34fdf15 + c59ad84 commit eb115a7

File tree

10 files changed

+181
-89
lines changed

10 files changed

+181
-89
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rocket_csrf_token"
3-
version = "0.3.2"
3+
version = "0.3.3"
44
authors = ["Alex Kotov <[email protected]>", "Mahmoud Harmouch <[email protected]>"]
55
edition = "2021"
66
description = "CSRF (Cross-Site Request Forgery) protection for Rocket web framework"

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ fn rocket() -> _ {
3737
::default()
3838
.with_cookie_name("foobar")
3939
.with_cookie_len(64)
40-
.with_lifetime(rocket::time::Duration::days(3))
40+
.with_lifetime(Some(rocket::time::Duration::days(3)))
4141
)
4242
)
4343
.attach(Template::fairing())
@@ -115,9 +115,9 @@ See the complete code in [minimal example](examples/minimal).
115115

116116
## TODO
117117

118-
- [X] Add fairing to verify all requests as an option (Requires unit tests).
119-
- [X] Verify `X-CSRF-Token` header (Requires unit tests).
120-
- [X] Set cookie to expire with session (Requires unit tests).
118+
- [X] Add fairing to verify all requests as an option.
119+
- [X] Verify `X-CSRF-Token` header.
120+
- [X] Set cookie to expire with session.
121121
- [ ] Add [data guard](https://api.rocket.rs/v0.5-rc/rocket/data/trait.FromData.html) to verify forms with a guard.
122122
- [ ] Add helpers to render form field.
123123
- [ ] Add helpers to add HTML meta tags for Ajax with `X-CSRF-Token` header (WIP).

examples/minimal/.env

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ROCKET_LOG_LEVEL=debug # one of `critical`, `normal`, `debug`, `off`
2+
ROCKET_SECRET_KEY=b28ad40f62b3ba9a7b2c114a483383583d460ddc914dbc3f4238a7419e1805f2a4a8412dd27254d7a321da49

examples/minimal/Cargo.lock

Lines changed: 8 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/minimal/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2021"
66
publish = false
77

88
[dependencies]
9+
dotenv = "0.15.0"
910
rocket = "=0.5.0-rc.3"
1011
rocket_csrf_token = { path = "../.." }
1112
rocket_dyn_templates = { version = "0.1.0-rc.3", features = ["handlebars"] }

examples/minimal/README.md

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,19 +14,31 @@
1414

1515
![App Demo](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lcpfehq4rsjpwrjjehvr.png)
1616

17+
The cookie's expiration coincides with the end of the user's session. This alignment occurs because the token's lifespan is deliberately configured as `None`. By setting the lifespan to `None`, the token implicitly adopts the same lifespan as the session, which is the default behavior. This means that when the user's session ends, the token, being closely tied to it, also expires. This mechanism ensures that the token remains valid and active only as long as the session itself, enhancing security and reliability.
18+
19+
![Session Cookie](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nbrd2kxsm91kuvtdm240.png)
20+
1721
## 🔒 CSRF Protection
1822

1923
This project incorporates robust CSRF protection mechanisms. CSRF attacks occur when unauthorized requests are made on behalf of a user without their consent. Rocket's CSRF protection ensures that form submissions contain a valid CSRF token, significantly enhancing the security of your web forms. 🌐
2024

2125
## 🧪 Testing CSRF Protection
2226

23-
To test the CSRF protection, you can use the following `curl` command:
27+
To rigorously assess the effectiveness of your Cross-Site Request Forgery (CSRF) protection mechanisms, you can employ the following `curl` command:
28+
29+
```bash
30+
curl -X POST -d "authenticity_token=invalid" -d "text=sus" http://127.0.0.1:8000/comments
31+
```
32+
33+
When executing this command, you should anticipate receiving a "403 Forbidden: Unauthorized Access" response from your Rocket application. Concurrently, the application will raise an error message stating "Error: Request lacks X-CSRF-Token." This outcome is a direct consequence of the provided `authenticity_token` being invalid. Furthermore, the request fails to include the essential `X-CSRF-Token` header. Subsequently, the CSRF token validation mechanism within your application rightfully rejects the request.
34+
35+
To further evaluate your CSRF defenses, you can simulate a scenario where the `X-CSRF-Token` header is explicitly set as follows:
2436

2537
```bash
26-
curl -X POST -d "authenticity_token=invalid&text=sus" http://127.0.0.1:8000/comments
38+
curl -X POST -H "X-CSRF-Token: invalid" -d "authenticity_token=invalid" -d "text=sus" http://127.0.0.1:8000/comments
2739
```
2840

29-
Running this command will result in a "403 Forbidden: Unauthorized Access" response. This occurs because the provided `authenticity_token` is invalid, and the CSRF token validation in the application rightfully rejects the request.
41+
In this scenario, the Rocket application will respond by displaying the error message "Error: CSRF token verification failed!" This time, both the provided `authenticity_token` and the supplied `X-CSRF-Token` header are determined to be invalid, resulting in a test of your CSRF protection.
3042

3143
## ✅ Successful POST Request
3244

examples/minimal/src/main.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ extern crate rocket;
55
#[macro_use]
66
extern crate serde_derive;
77

8+
use dotenv;
89
use rocket::form::Form;
910
use rocket::request::{FlashMessage, FromRequest};
1011
use rocket::response::{Flash, Redirect};
@@ -37,13 +38,20 @@ impl<'r> FromRequest<'r> for Authenticated {
3738
}
3839
}
3940

40-
#[launch]
41-
fn rocket() -> _ {
41+
#[rocket::main]
42+
async fn main() -> Result<(), rocket::Error> {
43+
dotenv::dotenv().ok();
4244
rocket::build()
43-
.attach(rocket_csrf_token::Fairing::default())
45+
.attach(rocket_csrf_token::Fairing::new(
46+
rocket_csrf_token::CsrfConfig::default().with_lifetime(None),
47+
))
4448
.attach(Template::fairing())
4549
.register("/", catchers![not_authorized])
4650
.mount("/", routes![index, new, create])
51+
.launch()
52+
.await
53+
.expect("Launch Error");
54+
Ok(())
4755
}
4856

4957
#[get("/")]

0 commit comments

Comments
 (0)