Auth Bypass in Actix with Session Cookies
Auth Bypass in Actix with Session Cookies — how this specific combination creates or exposes the vulnerability
An Auth Bypass in Actix using Session Cookies occurs when session identifiers are not properly validated, exposed, or protected, allowing an authenticated state to be assumed without valid credentials. This specific combination is common in Rust-based Actix-web applications that rely on cookie-based session management without enforcing strict validation, integrity checks, or secure transmission.
At a high level, Actix-web can store session data in cookies signed with a server-side secret. If the application fails to validate the session signature, does not enforce SameSite and Secure flags, or uses predictable session identifiers, an attacker can forge or replay cookie values to impersonate users. This maps to BOLA/IDOR and Authentication findings in middleBrick scans, where unauthenticated or low-privilege actors can access or escalate privileges via manipulated session cookies.
Consider a typical vulnerable Actix route that reads a session cookie and grants access based solely on its presence:
use actix_web::{web, App, HttpResponse, HttpServer, Responder};
use actix_session::{CookieSession, Session};
async fn profile(session: Session) -> impl Responder {
if let Some(user_id) = session.get::("user_id").unwrap() {
HttpResponse::Ok().body(format!("Profile for user: {}", user_id))
} else {
HttpResponse::Unauthorized().body("Not authenticated")
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(CookieSession::signed(&[0; 32]).secure(false)) // Insecure: not HTTPS, weak key
.route("/profile", web::get().to(profile))
})
.bind("127.0.0.1:8080")?
.run()
.await
}
In this example, the session cookie is signed but the server uses a static key and secure(false), which allows the cookie to be transmitted over HTTP. An attacker on the same network can intercept or modify the cookie. Additionally, if the application does not verify the scope of permissions encoded in the session (e.g., role or tenant ID), an attacker can change the user_id in the cookie to access another user’s profile, resulting in IDOR or BOLA.
Another common pattern is deserialization or direct parsing of cookie values without verifying integrity. If the session store is not cryptographically bound to the request context (e.g., missing binding to IP or user-agent), session fixation or replay becomes feasible. middleBrick tests for these weaknesses by probing endpoints without authentication and attempting to manipulate session identifiers to access unauthorized resources.
Because Actix-web is often used in high-performance services, developers may assume that cookie signing alone is sufficient. However, without additional checks like secure flag enforcement, SameSite policies, and strict validation of session contents, Auth Bypass via Session Cookies remains a realistic threat. The scanner findings typically highlight missing Secure flags, lack of scope validation, and use of predictable signing keys, all of which contribute to a higher risk score.
Session Cookies-Specific Remediation in Actix — concrete code fixes
Remediation focuses on ensuring session cookies are cryptographically strong, transmitted securely, and validated in context. The following code demonstrates a hardened configuration for Actix-web session management:
use actix_web::{web, App, HttpResponse, HttpServer, Responder, dev::ServiceRequest};
use actix_session::{CookieSession, storage::CookieSessionStore};
use actix_web_httpauth::extractors::bearer::BearerAuth;
async fn profile(session: actix_session::Session) -> impl Responder {
// Validate session integrity and scope
if let (Some(user_id), Some(role)) = (session.get::("user_id").unwrap(), session.get::("role").unwrap()) {
// Enforce tenant or scope checks here if applicable
HttpResponse::Ok().body(format!("Profile for {} with role {}", user_id, role))
} else {
HttpResponse::Unauthorized().body("Invalid session")
}
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
HttpServer::new(|| {
App::new()
.wrap(
CookieSession::signed(&ring::signature::Ed25519KeyPair::generate(&ring::signature::ED25519).unwrap().as_ref())
.secure(true) // Enforce HTTPS transmission
.http_only(true)
.same_site(actix_web::cookie::SameSite::Strict)
.max_age(time::Duration::hours(1))
)
.route("/profile", web::get().to(profile))
})
.bind("0.0.0.0:8443")?
.run()
.await
}
Key changes include:
secure(true)ensures cookies are only sent over HTTPS, preventing network interception.http_only(true)mitigates XSS-based cookie theft.same_site(Strict)reduces the risk of cross-site request forgery and unauthorized cross-origin sends.- Using a dynamically generated Ed25519 key for signing prevents static key exposure; rotate keys periodically in production.
- Explicitly validating multiple session attributes (e.g., role, tenant) ensures that privilege changes via cookie manipulation are detected.
For additional assurance, combine session cookies with short-lived tokens or re-authentication for sensitive operations. middleBrick’s CLI can verify these configurations by scanning your endpoint and flagging missing Secure flags or weak signing mechanisms.
Developers should also consider binding sessions to request metadata such as IP or user-agent where appropriate, although this must be balanced with usability in mobile or roaming scenarios. The goal is to reduce the attack surface so that even if a cookie is intercepted, it cannot be reused across contexts or users.
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 |