Insecure Direct Object Reference in Actix with Mongodb
Insecure Direct Object Reference in Actix with Mongodb — how this specific combination creates or exposes the vulnerability
Insecure Direct Object Reference (IDOR) occurs when an API exposes a reference to an internal object—such as a MongoDB document identifier—and allows an unauthenticated or insufficiently authorized actor to manipulate that reference to access or modify data they should not see. In an Actix-web service that uses MongoDB as the backend, this typically arises when route parameters (e.g., /users/{user_id}/profile) or query parameters are used directly to construct database queries without verifying that the requesting actor has permission to access the targeted document.
Consider an Actix handler that retrieves a user profile using a user ID supplied in the URL. If the handler uses the raw path parameter to form a MongoDB filter like { "_id": ObjectId("...") } without confirming that the authenticated subject (if any) owns or is allowed to view that document, the endpoint becomes vulnerable. An attacker can change the supplied ID to another valid ObjectId and potentially enumerate or access other users’ profiles. Because the API surface is unauthenticated (black-box scanning), an attacker can probe IDs sequentially or use a list of known ObjectIds to harvest data, a classic enumeration pattern flagged by the Authentication and BOLA/IDOR checks in middleBrick’s 12 security checks.
Compounding the risk, MongoDB’s _id values are often predictable (e.g., timestamps with incrementing counters) or can be guessed when insufficient randomness is used. If the Actix service also exposes secondary indexes (such as email or username) without access controls, an attacker can pivot by those fields and indirectly reference documents. MiddleBrick’s checks for Property Authorization and Input Validation are designed to surface these exposures by testing whether object references are validated against the requester’s context rather than trusted server-side identifiers.
Moreover, if the API reflects MongoDB error messages—such as “document not found” versus “access denied”—it can leak enumeration signals that aid further attacks. The scanner’s unauthenticated endpoint probing can surface these behavioral differences, highlighting IDOR alongside information exposure risks. Because the scan runs in 5–15 seconds and requires no credentials, it quickly demonstrates how an exposed route parameter can lead to unauthorized data access in this stack.
Mongodb-Specific Remediation in Actix — concrete code fixes
To mitigate IDOR when using MongoDB with Actix, enforce authorization checks on the server side for every object reference, and avoid using raw user input to directly address documents. Instead of trusting route or query parameters, resolve the intended resource through the authenticated subject’s associations, and use MongoDB queries that combine the document identifier with ownership or permission fields.
For example, assume you have a users collection where each document includes an owner_id that ties the document to the authenticated user. A safe Actix handler would first resolve the authenticated identity (from session, token, or other secure context), then construct a filter that combines both the user-supplied reference and the ownership constraint:
use actix_web::{web, HttpResponse, Result};
use mongodb::{bson::{doc, oid::ObjectId}, options::FindOneOptions, Client};
async fn get_user_profile(
client: web::Data,
path: web::Path,
// Assume get_authenticated_user_id returns the subject from a secure source
get_authenticated_user_id: impl Fn() -> Option,
) -> Result {
let user_id = match get_authenticated_user_id() {
Some(id) => id,
None => return Ok(HttpResponse::Unauthorized().finish()),
};
let requested_oid = match ObjectId::parse_str(&path) {
Ok(id) => id,
Err(_) => return Ok(HttpResponse::BadRequest().body("invalid id")),
};
let coll = client.database("appdb").collection("users");
let filter = doc! {
"_id": requested_oid,
"owner_id": user_id,
};
let opts = FindOneOptions::builder().build();
let maybe_doc = coll.find_one(filter, opts).await.map_err(|e| {
actix_web::error::ErrorInternalServerError(e.to_string())
})?;
match maybe_doc {
Some(doc) => Ok(HttpResponse::Ok().json(doc)),
None => Ok(HttpResponse::NotFound().body("not found or access denied")), // avoid leaking specifics
}
}
This pattern ensures that even if an attacker supplies a valid ObjectId, they cannot access documents whose owner_id does not match the authenticated subject. The same principle applies when referencing related resources such as posts or invoices—always include a tenant or ownership predicate in the MongoDB filter.
Additionally, normalize error handling to avoid information leakage. Return a generic “not found or access denied” response for both missing documents and insufficient permissions, so enumeration becomes harder. Use strong, random identifiers where possible, and consider adding a lightweight access control layer before hitting MongoDB. MiddleBrick’s findings for BOLA/IDOR and Property Authorization can guide you in validating these patterns, and the CLI tool (middlebrick scan <url>) can be integrated into development workflows to detect regressions early.
Related CWEs: bolaAuthorization
| CWE ID | Name | Severity |
|---|---|---|
| CWE-250 | Execution with Unnecessary Privileges | HIGH |
| CWE-639 | Insecure Direct Object Reference | CRITICAL |
| CWE-732 | Incorrect Permission Assignment | HIGH |