iron_csrf/
lib.rs

1//! Crate providing cross-site request forgery (CSRF) protection for Iron.
2//!
3//! ## Overview
4//!
5//! `iron_csrf` is used as `iron::AroundMiddleware` that checks all requests with the HTTP method
6//! POST, PUT, PATCH, and DELETE for the presence of a CSRF token, and it generates tokens that can
7//! be  used inside the application for use when generating the `Response`. A more complete
8//! reference implementation can be found on
9//! [github](https://github.com/heartsucker/iron-reference).
10//!
11//! ## Hello, CSRF.
12//!
13//! The following is a simple server that prints the contents of the CSRF token. It  demonstrates
14//! how to wrap the middleware and access the string contents of the `CsrfToken`.
15//!
16//! ```
17//! extern crate csrf;
18//! extern crate iron;
19//! extern crate iron_csrf;
20//!
21//! use csrf::{CsrfToken, AesGcmCsrfProtection};
22//! use iron::AroundMiddleware;
23//! use iron::prelude::*;
24//! use iron::status;
25//! use iron_csrf::{CsrfProtectionMiddleware, CsrfConfig};
26//!
27//! fn main() {
28//!     // Set up CSRF protection with the default config
29//!     let key = *b"01234567012345670123456701234567";
30//!     let protect = AesGcmCsrfProtection::from_key(key);
31//!     let config = CsrfConfig::default();
32//!     let middleware = CsrfProtectionMiddleware::new(protect, config);
33//!
34//!     // Set up routes
35//!     let handler = middleware.around(Box::new(index));
36//!
37//!     // Make and start the server
38//!     Iron::new(handler); //.http("localhost:8080").unwrap();
39//! }
40//!
41//! fn index(request: &mut Request) -> IronResult<Response> {
42//!     let token = request.extensions.get::<CsrfToken>().unwrap();
43//!     let msg = format!("Hello, CSRF Token: {}", token.b64_string());
44//!     Ok(Response::with((status::Ok, msg)))
45//! }
46//!
47//! ```
48//!
49//! ## Protection
50//! There are three ways that `iron_csrf` checks for the presence of a CSRF token.
51//!
52//! - The field `csrf-token` in requests with `Content-Type: application/x-www-form-urlencoded`
53//! - The query parameter `csrf-token`
54//! - The header `X-CSRF-Token`
55//!
56//! The selection is done short circuit, so the first present wins, and retrieval on fails if the
57//! token is not present in any of the fields.
58//!
59//! Tokens have a time to live (TTL) that defaults to 3600 seconds. If a token is stale, validation
60//! will fail.
61//!
62//! In the provided implementations, tokens are cryptographically signed, so tampering with a token
63//! or its signature will cause the validation to fail. Validation failures will return a `403
64//! Forbidden`.
65//!
66//! Signatures and other data needed for validation are stored in a cookie that is sent to the user
67//! via the `Set-Cookie` header.
68//!
69//! ## Unsupported: Token in `multipart/form-data`
70//! Because of how the `iron` library handles middleware and streaming requests, it is not possible
71//! (or at least not feasible) at this time to intercept requests and check the multipart forms. To
72//! add protection for requests with `Content-Type: multipart/form-data`, you should include the
73//! CSRF token in the query string.
74
75#![deny(missing_docs)]
76
77#[cfg(test)]
78#[macro_use]
79extern crate lazy_static;
80#[macro_use]
81extern crate log;
82
83mod core;
84pub use crate::core::*;
85
86/// Re-exports the `csrf` crate.
87pub mod csrf {
88    pub use csrf::*;
89}