HIGH session fixationactixcockroachdb

Session Fixation in Actix with Cockroachdb

Session Fixation in Actix with Cockroachdb — how this specific combination creates or exposes the vulnerability

Session fixation occurs when an application accepts an attacker-supplied session identifier and later authenticates the user against that same identifier. In an Actix-web application using CockroachDB as the session store, the risk arises when session identifiers are created or accepted without validation and are persisted in CockroachDB without server-side regeneration upon authentication.

Actix-web does not provide session management by default; developers typically use crates such as actix-session with a CockroachDB-backed store (e.g., via actix-session-cockroachdb or a custom implementation using the CockroachDB SQL driver). If the session cookie value is copied from an unauthenticated context (e.g., a query parameter or a predictable token) and later used to look up a record in CockroachDB without regeneration after login, the session ID remains fixed across authentication boundaries.

CockroachDB’s strong consistency and SQL semantics mean that session records are durable and can be reliably queried by session ID. An attacker who can force a victim to use a known session ID (e.g., via URL injection or a crafted link) can, after the victim authenticates, use the same ID to hijack the session. Because the session data is stored in CockroachDB, the fixation persists across server restarts and is tied to the user record in the database, increasing the window for exploitation.

For example, if the application uses an unauthenticated route like /login?session_id=abc123 and then binds abc123 to the authenticated user in CockroachDB without issuing a new session identifier, the fixed ID becomes a direct vector. MiddleBrick’s unauthenticated scan would flag this as a BOLA/IDOR-related finding, noting that session identifiers are not rotated on authentication and are stored in a strongly consistent database where they remain retrievable.

To detect such issues programmatically, tools like middleBrick analyze OpenAPI specs and runtime behavior for missing session regeneration patterns and unauthenticated session usage, without making assumptions about internal architecture. Remediation focuses on ensuring session identifiers are regenerated server-side immediately after authentication and that session records in CockroachDB are tightly scoped to authenticated contexts.

Cockroachdb-Specific Remediation in Actix — concrete code fixes

Remediation centers on regenerating session identifiers on authentication and ensuring CockroachDB records are keyed only to authenticated sessions. Below is a concrete, syntactically correct example using actix-session with a CockroachDB store implemented via the sqlx crate. The approach rotates the session ID after successful authentication and invalidates the previous CockroachDB row.

use actix_session::{Session, SessionMiddleware, storage::CookieSessionStore};
use actix_web::{web, App, HttpServer, HttpResponse, HttpRequest};
use sqlx::PgPool;
use uuid::Uuid;

// After authentication, regenerate session and store user_id in CockroachDB
async fn login(
    session: Session,
    pool: web::Data,
    form: web::Form,
) -> HttpResponse {
    // Validate credentials against CockroachDB
    let user = validate_user(&pool, &form.username, &form.password).await;
    if user.is_none() {
        return HttpResponse::Unauthorized().finish();
    }

    // Rotate session key: generate new ID and persist user association
    let new_session_id = Uuid::new_v4().to_string();
    session.regenerate(); // actix-session helper to rotate cookie
    // Explicitly update the underlying store record in CockroachDB
    sqlx::query!(
        "UPDATE sessions SET user_id = $1 WHERE session_id = $2",
        user.unwrap().id,
        new_session_id
    )
    .execute(pool.as_ref())
    .await
    .expect("Failed to update session in CockroachDB");

    // Ensure the cookie reflects the new session ID
    if let Some(cookie) = session.cookie() {
        HttpResponse::Ok()
            .cookie(cookie.clone())
            .finish()
    } else {
        HttpResponse::InternalServerError().finish()
    }
}

// Middleware-like guard to ensure session maps to authenticated user in CockroachDB
async fn ensure_authenticated(
    session: Session,
    pool: web::Data,
    req: HttpRequest,
) -> Result {
    let session_id = session.id().map_err(|_| HttpResponse::Unauthorized().finish())?;
    let record: (Option,) = sqlx::query_as(
        "SELECT user_id FROM sessions WHERE session_id = $1"
    )
    .bind(&session_id)
    .fetch_optional(pool.as_ref())
    .await
    .map_err(|_| HttpResponse::InternalServerError().finish())?;

    if record.map(|r| r.0).flatten().is_none() {
        return Err(HttpResponse::Unauthorized().finish());
    }
    Ok(HttpResponse::Ok().finish())
}

async fn validate_user(pool: &PgPool, username: &str, password: &str) -> Option {
    sqlx::query_as!(User, "SELECT id, username FROM users WHERE username = $1 AND password = crypt($2, password_hash)", username, password)
        .fetch_optional(pool)
        .await
        .ok()?
        .first()
        .cloned()
}

struct User { id: i64, username: String }
struct LoginData { username: String, password: String }
"

Key points in this remediation:

  • session.regenerate() ensures the session identifier changes after authentication, preventing fixation.
  • The CockroachDB sessions table is updated with the new session ID and associated user ID, maintaining a 1:1 mapping to the authenticated user.
  • Unauthenticated session records are never used to derive user identity; validation always queries CockroachDB for the current session-to-user mapping.

For broader protection, apply the same regeneration pattern to any route that transitions from unauthenticated to authenticated state, and ensure session cookies are scoped with HttpOnly, Secure, and appropriate SameSite attributes. MiddleBrick’s scans can verify that your OpenAPI spec and implementation align with these regeneration patterns.

Frequently Asked Questions

How can I detect session fixation vulnerabilities in my Actix + CockroachDB API using middleBrick?
Run a middleBrick scan against your unauthenticated API endpoints. The scanner checks for missing session regeneration on authentication and flags endpoints where session identifiers are accepted or reused without server-side rotation. Review the BOLA/IDOR and Authentication findings in the report for specific remediation guidance.
Does CockroachDB’s consistency make session fixation worse than with other databases?
CockroachDB’s strong consistency means session records are immediately readable and durable, which can make fixed session identifiers persist longer and be more reliably abused. The mitigation is to rotate session IDs on authentication and ensure CockroachDB rows are tightly bound to authenticated sessions only.