Skip to content

🌊 A stateless CSRF middleware for tower.

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT
Notifications You must be signed in to change notification settings

its-danny/tower-surf

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

25 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌊 tower-surf

A stateless CSRF middleware for tower.

Crates MSRV Docs CI

πŸ„β€β™‚οΈ Overview

This crate uses the Double Submit Cookie Pattern to mitigate CSRF.

How it works

  • Secret key: You provide a secret key used to sign CSRF tokens. This secret is secured by secstr and only in memory as plaintext during the signing and validating processes. For more information on managing your secret key, see OWASP's Cryptographic Storage Cheat Sheet).
  • Token creation:
    • We generate a message by combining a unique session identifier with a cryptographically secure random value (using the rand crate).
    • We then create an signature using the secret key and the message.
    • The token is formed by concatenating the signature and the message.
  • Token storage:
    • The server sends the token to the client in two ways:
      • As a cookie (handled by us).
      • In the header of subsequent requests (handled by you).
  • Token validation:
    • For each incoming request that would mutate state:
      • We extract the token from the request headers.
      • We split the token into the signature and the message.
      • We recalculate the signature using the secret key and compare them.
    • If the signature is valid and the token matches the value stored in the cookie, the request is allowed to proceed.

Cookies

By default, the cookies are set to HTTPOnly, SameSite: Strict, and Secure.

πŸ“¦ Install

[dependencies]
tower-surf = "0.3.0"

πŸ—οΈ Usage

With axum

use std::net::SocketAddr;

use axum::{routing::get, Router};
use http::StatusCode;
use tower_surf::{Surf, Token};

#[tokio::main]
async fn main() {
    let app = Router::new()
        .route("/login", get(login)).route("/logout", get(logout))
        .layer(Surf::new("secret-key").secure(false));

    let addr = SocketAddr::from(([127, 0, 0, 1], 3000));
    let listener = tokio::net::TcpListener::bind(&addr).await.unwrap();

    axum::serve(listener, app.into_make_service())
        .await
        .unwrap();
}

async fn login(token: Token) -> Result<StatusCode, StatusCode> {
    token.set("unique-session-id").map_err(|_| StatusCode::INTERNAL_SERVER_ERROR)?;

    Ok(StatusCode::OK)
}

async fn logout(token: Token) -> StatusCode {
    token.reset();

    StatusCode::OK
}

Note

See the examples for a full example.

πŸ₯° Thank you

About

🌊 A stateless CSRF middleware for tower.

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

No packages published