Auth Bypass in Axum with Session Cookies
Auth Bypass in Axum with Session Cookies — how this specific combination creates or exposes the vulnerability
Auth bypass in Axum when session cookies are used typically arises from missing or inconsistent validation on protected routes. Axum does not enforce authentication or authorization by itself; it relies on application logic to inspect session cookies and derive identity. If routes that should require a valid session do not consistently check the cookie, deserialize the session store, or validate its integrity, an unauthenticated or low-privilege user may reach endpoints that should be restricted.
Common patterns that create risk include:
- Not verifying the session cookie on certain HTTP methods or paths, such as GET handlers used for rendering forms that also accept state-changing actions.
- Relying on client-side state or unsigned cookies that can be tampered with, allowing an attacker to forge a valid-looking session identifier.
- Insecure session storage or serialization that permits manipulation of user roles or scopes stored in the cookie value.
- Middleware that conditionally skips checks based on URL prefixes, enabling authenticated-only endpoints to be accessed when the prefix does not match the guard logic.
Because middleBrick tests unauthenticated attack surfaces, it can flag routes where session-based auth is missing or inconsistent, even when the endpoint appears protected by route guards. Findings often map to OWASP API Top 10 Broken Object Level Authorization (BOLA) and Broken Authentication, and may align with PCI-DSS and SOC2 controls related to access management.
In an Axum service, a typical vulnerable pattern is exposing administrative functionality under a prefix like /admin while only checking the cookie in a subset of handlers. middleBrick’s parallel checks — including Authentication, BOLA/IDOR, and Property Authorization — increase the likelihood of detecting these gaps without requiring authenticated scans.
Session Cookies-Specific Remediation in Axum — concrete code fixes
Secure session cookie handling in Axum requires explicit validation on every protected handler or, preferably, centralized via middleware. Always treat the cookie as untrusted and validate it against a server-side store or a signed token with limited scope.
Below are concrete, working examples for Axum that demonstrate secure session cookie usage.
1. Signed cookie approach using tower-cookies and cookie
Use signed cookies so the server can verify integrity. Keep sensitive claims minimal and re-validate on each request.
use axum::{routing::get, Router, extract::State, http::StatusCode};
use serde::{Serialize, Deserialize};
use tower_cookies::{Cookie, Cookies};
use std::sync::Arc;
use jsonwebtoken::{encode, Header, EncodingKey};
#[derive(Serialize, Deserialize, Debug, Clone)]
struct SessionClaims {
sub: String,
role: String,
exp: usize,
}
async fn handler_protected(State(state): State, cookies: Cookies) -> (StatusCode, String) {
let cookie = cookies.get("session").ok_or_else(|| (StatusCode::UNAUTHORIZED, "Missing cookie"))?;
let token = cookie.value().to_string();
let validation = jsonwebtoken::Validation::new(jsonwebtoken::Algorithm::HS256);
let token_data = jsonwebtoken::decode::
2. Server-side session store lookup
Store session data server-side (e.g., Redis) and only store a session ID in the cookie. Validate existence and ownership on each request.
use axum::{routing::get, Router, extract::State, http::StatusCode};
use serde::{Serialize, Deserialize};
use std::sync::Arc;
use redis::AsyncCommands;
#[derive(Serialize, Deserialize, Debug, Clone)]
struct SessionData {
user_id: String,
role: String,
}
struct AppState {
redis_client: redis::Client,
}
async fn handler_admin(State(state): State<Arc<AppState>>, cookies: tower_cookies::Cookies) -> (StatusCode, String) {
let session_id = cookies.get("session_id").ok_or_else(|| (StatusCode::UNAUTHORIZED, "Missing session cookie"))?;
let mut conn = state.redis_client.get_async_connection().await.map_err(|_| (StatusCode::INTERNAL_SERVER_ERROR, "Redis error"))?;
let session_data: Option<SessionData> = redis::from_redis_value(&redis::cmd("GET").arg(session_id.value()).query_async(&mut conn).await.unwrap_or_default()).ok();
let data = session_data.ok_or_else(|| (StatusCode::UNAUTHORIZED, "Invalid session"))?;
if data.role != "admin" {
return Err((StatusCode::FORBIDDEN, "Forbidden").into());
}
Ok((StatusCode::OK, format!("Admin area for user: {}", data.user_id)))
}
async fn login_handler(State(state): State<Arc<AppState>>, user: String) -> (StatusCode, String) {
let session_id = uuid::Uuid::new_v4().to_string();
let session_data = SessionData { user_id: user.clone(), role: "admin".to_string() };
let serialized = serde_json::to_string(&session_data).unwrap();
let mut conn = state.redis_client.get_async_connection().await.unwrap();
redis::cmd("SET").arg(&session_id).arg(serialized).query_async(&mut conn).await.unwrap();
// In production, set Secure; HttpOnly; SameSite=Strict or Lax
cookies.add(tower_cookies::Cookie::build(("session_id", session_id)).http_only(true).secure(true).same_site(tower_cookies::SameSite::Strict).finish());
(StatusCode::OK, "Logged in".to_string())
}
Middleware guard example
Centralize checks with an Axum middleware that validates the session before reaching protected routes.
use axum::{extract::Extension, middleware::Next, response::Response, BoxError};
use std::sync::Arc;
async fn session_middleware(
Extension(state): Extension<Arc<AppState>>,
cookies: tower_cookies::Cookies,
next: Next,
) -> Result<Response, BoxError> {
let cookie = cookies.get("session").ok_or_else(|| (StatusCode::UNAUTHORIZED, "Missing session"))?;
// validate cookie/session with state, reject if invalid
next.run(Extension(state), cookies).await
}
By enforcing validation in middleware and avoiding broad prefix-based skips, you reduce the chance of an auth bypass. middleBrick’s checks for Authentication, BOLA/IDOR, and Property Authorization help confirm that protections are consistently applied across endpoints.
Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |