axum-tower-sessions-csrf

Crates.ioaxum-tower-sessions-csrf
lib.rsaxum-tower-sessions-csrf
version0.1.1
created_at2025-12-11 23:25:18.691023+00
updated_at2025-12-11 23:45:08.814178+00
descriptionCSRF protection for Axum using tower-sessions with the Synchronizer Token Pattern
homepage
repositoryhttps://github.com/cavebatsofware/axum-tower-sessions-csrf
max_upload_size
id1980742
size49,153
Cave Bats Of Ware (cavebatsofware)

documentation

README

Cargo Check Cargo Format Lint Cargo Audit crates.io

axum-tower-sessions-csrf

Crates.io Documentation License

CSRF protection for Axum using tower-sessions, implementing the Synchronizer Token Pattern as recommended by OWASP.

Features

  • Cryptographically secure token generation
  • Session-based token storage (no cookies needed)
  • Constant-time token validation (prevents timing attacks)
  • Automatic validation on POST/PUT/DELETE/PATCH requests
  • Simple integration with existing Axum applications
  • Lightweight with minimal dependencies

Installation

[dependencies]
axum-tower-sessions-csrf = "0.1"
tower-sessions = "0.14"

Quick Start

use axum::{routing::{get, post}, Router};
use axum::middleware::from_fn;
use tower_sessions::{MemoryStore, SessionManagerLayer};
use axum_tower_sessions_csrf::CsrfMiddleware;

#[tokio::main]
async fn main() {
    // Setup session layer
    let session_store = MemoryStore::default();
    let session_layer = SessionManagerLayer::new(session_store);

    // Build your app with CSRF protection
    let app = Router::new()
        .route("/", get(index))
        .route("/submit", post(submit))
        .layer(from_fn(CsrfMiddleware::middleware))  // Add CSRF middleware
        .layer(session_layer);                        // Session layer must be last

    // Run your server...
}

Usage

Backend: Get CSRF Token

use tower_sessions::Session;
use axum::Json;
use axum_tower_sessions_csrf::get_or_create_token;

async fn get_token(session: Session) -> Result<Json<String>, String> {
    let token = get_or_create_token(&session).await?;
    Ok(Json(token))
}

Frontend: Include Token in Requests

// Fetch CSRF token
const response = await fetch('/api/csrf-token');
const { token } = await response.json();

// Include in state-changing requests
await fetch('/api/submit', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json',
        'x-csrf-token': token,  // Required header
    },
    body: JSON.stringify(data),
});

How It Works

  1. Token Generation: Generates a 64-character hex token (32 random bytes)
  2. Session Storage: Stores token server-side in tower-sessions
  3. Header Validation: Validates x-csrf-token header on POST/PUT/DELETE/PATCH
  4. Constant-Time Comparison: Prevents timing attacks during validation

Security Considerations

  • Tokens are stored server-side (not in cookies)
  • Constant-time comparison prevents timing attacks
  • Cryptographically secure random token generation
  • Follows OWASP best practices https://devguide.owasp.org/

License

Licensed under either of:

at your option.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Commit count: 0

cargo fmt