HIGH insecure direct object referenceaxumfirestore

Insecure Direct Object Reference in Axum with Firestore

Insecure Direct Object Reference in Axum with Firestore — 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 Firestore document ID—and allows an authenticated user to act on or retrieve that object without verifying authorization. In Axum, route parameters or query values that directly map to Firestore document IDs can lead to IDOR when access controls are missing or incomplete. Firestore security rules alone do not enforce per-request authorization at the application layer; they are broad and often rely on the caller to pass the correct document path. If an Axum handler uses a user-supplied ID to construct a Firestore document reference and returns or modifies that document without checking ownership or permissions, the endpoint becomes vulnerable.

Consider an Axum handler that retrieves a user’s profile by ID from a Firestore collection users. If the handler trusts a route parameter like user_id and fetches the corresponding document without confirming that the authenticated subject is allowed to view that document, any authenticated user can enumerate or access others’ profiles by changing the ID. This is a classic IDOR. In Firestore, document IDs are often predictable (e.g., auto-generated or based on user UIDs), which makes enumeration straightforward. An attacker does not need to exploit a bug in Firestore rules; the flaw is in the Axum application logic that fails to validate authorization before performing the read or write.

Another common pattern is using Firestore references in URLs for shared resources, such as a projects/{project_id}/tasks/{task_id} structure. If the Axum handler resolves the project and task IDs from the URL and performs operations without verifying that the requesting user has access to the specified project, the handler exposes an IDOR. Firestore rules might permit reads if the document field visibility is set to public, but the application may incorrectly serve private data because it never checks the authenticated user’s membership in the project. This mismatch between application-level authorization and Firestore rules is what enables IDOR in the Axum + Firestore combination.

Firestore-Specific Remediation in Axum — concrete code fixes

To remediate IDOR in Axum with Firestore, enforce authorization checks in the application layer before constructing or using Firestore document references. Always resolve the authenticated subject (e.g., from session or token) and compare it with resource ownership or allowed scopes. Do not rely solely on Firestore security rules for access control at the endpoint level. Below are concrete Axum handler examples that demonstrate secure handling of Firestore document references.

First, ensure you map the authenticated user’s identity into the request extensions so handlers can access it consistently. In Axum, you can use request extensions to pass the subject ID after authentication:

use axum::{Extension, Json};
use firebase_admin_rs as firestore;
use serde::{Deserialize, Serialize};
use std::sync::Arc;

#[derive(Clone)]
struct AppState {
    firestore: Arc,
    subject_id: String, // set by auth middleware
}

async fn get_user_profile(
    Extension(state): Extension,
    // route parameter from paths like /users/:user_id
    user_id: String,
) -> Result, (axum::http::StatusCode, String)> {
    // Enforce authorization: subject can only access their own profile
    if user_id != state.subject_id {
        return Err((axum::http::StatusCode::FORBIDDEN, "Unauthorized".to_string()));
    }
    let doc_ref = state.firestore.collection("users").doc(&user_id);
    let snapshot = doc_ref.get().await.map_err(|e| {
        (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
    })?;
    let data: serde_json::Value = snapshot.get_data().unwrap_or_default();
    Ok(Json(data))
}

This pattern ensures the handler compares the route parameter user_id with the authenticated subject ID before accessing Firestore. Even if the ID is predictable, the check prevents access to other users’ documents.

For hierarchical resources, such as projects and tasks, validate membership at each level. For example, confirm that the user is a member of the project before allowing access to a task within that project:

async fn get_task(
    Extension(state): Extension,
    (project_id, task_id): (String, String),
) -> Result, (axum::http::StatusCode, String)> {
    // Check project membership first
    let project_ref = state.firestore.collection("projects").doc(&project_id);
    let project_snapshot = project_ref.get().await.map_err(|e| {
        (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
    })?;
    if !project_snapshot.exists() {
        return Err((axum::http::StatusCode::NOT_FOUND, "Project not found".to_string()));
    }
    let members: Vec = project_snapshot
        .get_by_field("members")
        .unwrap_or_default();
    if !members.contains(&state.subject_id) {
        return Err((axum::http::StatusCode::FORBIDDEN, "Not a project member".to_string()));
    }
    // Fetch task under the project
    let task_ref = state
        .firestore
        .collection("projects")
        .doc(&project_id)
        .collection("tasks")
        .doc(&task_id);
    let task_snapshot = task_ref.get().await.map_err(|e| {
        (axum::http::StatusCode::INTERNAL_SERVER_ERROR, e.to_string())
    })?;
    let data: serde_json::Value = task_snapshot.get_data().unwrap_or_default();
    Ok(Json(data))
}

By validating project membership before accessing the task, you prevent IDOR across nested resources. Firestore rules can still provide a safety net, but the application must perform explicit checks to avoid insecure direct object references in Axum handlers.

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

Can Firestore security rules alone prevent IDOR in Axum handlers?
No. Firestore security rules are broad and do not enforce application-level authorization context. Axum handlers must explicitly verify that the authenticated subject is allowed to access the requested document before using its ID.
What should I do if my Firestore document IDs are predictable and I need to protect them in Axum?
Always compare the authenticated user’s identity with the document ID or ownership metadata in the handler. Use Axum request extensions to pass the subject ID after authentication, and enforce per-request checks before constructing Firestore document references.