HIGH insecure direct object referenceactixbearer tokens

Insecure Direct Object Reference in Actix with Bearer Tokens

Insecure Direct Object Reference in Actix with Bearer Tokens — how this combination creates or exposes the vulnerability

Insecure Direct Object Reference (BOLA/IDOR) occurs when an API exposes internal object references (e.g., database IDs) without verifying that the requesting actor has permission to access them. In Actix-web, this commonly arises when endpoints use path or query parameters to reference resources (such as /users/{user_id}/profile) and only check that a Bearer token is present, not whether the token’s subject is allowed to access the specific resource.

Consider an Actix endpoint that retrieves a user profile using a numeric ID from the URL and an access token in the Authorization header. If the handler extracts the token, confirms it is well-formed, and then directly loads the profile by ID without confirming ownership or authorization, the endpoint is vulnerable:

use actix_web::{web, HttpResponse, Error};
use serde::Deserialize;

#[derive(Deserialize)]
struct PathParams {
    user_id: u64,
}

async fn get_profile(
    params: web::Query,
    req: actix_web::HttpRequest,
) -> Result<HttpResponse, Error> {
    // Extract Bearer token
    let token = match req.headers().get("Authorization") {
        Some(h) => h.to_str().unwrap_or(""),
        None => return Ok(HttpResponse::Unauthorized().finish()),
    };
    if !token.starts_with("Bearer ") {
        return Ok(HttpResponse::BadRequest().body("Invalid auth scheme"));
    }
    // Vulnerable: no check that the authenticated subject owns or is allowed to access user_id
    let profile = fetch_user_from_db(params.user_id).await;
    Ok(HttpResponse::Ok().json(profile))
}

In this pattern, the Bearer token is used only for presence checks (e.g., authentication), but the handler does not enforce authorization scoped to the resource identified by user_id. An attacker who can guess or enumerate numeric IDs (or use leaked references) can read, modify, or delete other users’ data simply by supplying a valid Bearer token belonging to any user.

Two aspects amplify the risk in this combination:

  • Actix routes often expose identifiers directly in paths, making it easy to manipulate references (e.g., changing user_id=123 to user_id=124).
  • Bearer tokens typically identify the actor (subject), but do not carry object-level permissions. Relying solely on the token without additional checks conflates authentication with authorization, which is a common root cause of IDOR in resource-based APIs.

Other IDOR-prone patterns include using internal surrogate keys (e.g., sequential invoice IDs) in URLs while failing to confirm that the authenticated principal is associated with the target record. MiddleBrick’s scans detect this by correlating the presence of Bearer token usage with endpoints that accept direct object references and lack complementary authorization checks.

Bearer Tokens-Specific Remediation in Actix — concrete code fixes

Remediation centers on ensuring that for every direct object reference, the server verifies that the authenticated subject (derived from the Bearer token) has the necessary rights to the requested resource. Below are concrete, idiomatic Actix examples that implement this principle.

1. Include subject ownership in the authorization check: After validating the Bearer token, decode the subject claim (e.g., sub or a custom user identifier) and compare it with the resource owner before proceeding.

use actix_web::{web, HttpResponse, Error, dev::ServiceRequest};
use actix_web::http::header::HeaderValue;
use jsonwebtoken::{decode, Algorithm, DecodingKey, Validation};
use serde::{Deserialize, Serialize};

#[derive(Debug, Deserialize)]
struct Claims {
    sub: String,
    // include other standard or custom claims as needed
}

#[derive(Deserialize)]
struct PathParams {
    user_id: u64,
}

async fn get_profile(
    params: web::Query<PathParams>,
    req: actix_web::HttpRequest,
) -> Result<HttpResponse, Error> {
    // Extract and validate Bearer token
    let auth = req.headers().get("Authorization")
        .and_then(|v| v.to_str().ok())
        .filter(|s| s.starts_with("Bearer "))
        .map(|s| &s[7..])
        .ok_or_else(|| actix_web::error::ErrorUnauthorized("Invalid or missing Bearer token"))?;

    // Decode token and extract subject
    let token_data = decode::

This pattern decodes the JWT Bearer token, extracts the subject, and compares it to the resource’s owner, ensuring that users can only access their own data when IDs are directly referenced.

2. Use indirect references or mapping tables instead of raw IDs: Where possible, avoid exposing sequential or guessable IDs. Use UUIDs or map internal IDs to opaque references verified against an ownership table.

use actix_web::{web, HttpResponse, Error};
use uuid::Uuid;

#[derive(Deserialize)]
struct PathParams {
    profile_key: String, // opaque reference (e.g., UUID)
}

async fn get_profile_by_key(
    params: web::Query<PathParams>,
    req: actix_web::HttpRequest,
) -> Result<HttpResponse, Error> {
    let auth = req.headers().get("Authorization")
        .and_then(|v| v.to_str().ok())
        .filter(|s| s.starts_with("Bearer "))
        .map(|s| &s[7..])
        .ok_or_else(|| actix_web::error::ErrorUnauthorized("Invalid or missing Bearer token"))?;

    // Decode token as above to obtain subject (omitted for brevity)
    let subject = decode_bearer_subject(auth).await;

    // Map opaque key to a record and verify ownership
    let record = fetch_record_by_key(¶ms.profile_key).await
        .ok_or_else(|| actix_web::error::ErrorNotFound("Resource not found"))?;
    if record.owner_id != subject {
        return Err(actix_web::error::ErrorForbidden("Access denied"));
    }

    Ok(HttpResponse::Ok().json(record))
}

By combining Bearer token validation with per-resource authorization checks and avoiding direct exposure of mutable internal identifiers, you mitigate IDOR risks while preserving the utility of token-based authentication in Actix services.

Related CWEs: bolaAuthorization

CWE IDNameSeverity
CWE-250Execution with Unnecessary Privileges HIGH
CWE-639Insecure Direct Object Reference CRITICAL
CWE-732Incorrect Permission Assignment HIGH

Frequently Asked Questions

Does using Bearer tokens alone prevent IDOR in Actix APIs?
No. Bearer tokens authenticate the caller but do not enforce object-level permissions. Without explicit authorization checks that tie the token’s subject to the referenced resource, IDOR vulnerabilities remain.
What is a practical first step to find IDOR in Actix endpoints that use Bearer tokens?
Map endpoints that accept direct object identifiers (numeric IDs, slugs, keys) and verify whether each handler performs authorization relative to the authenticated subject from the Bearer token. Tools like MiddleBrick can help identify missing authorization checks by correlating token usage with object references.