HIGH insecure direct object referencefastapidynamodb

Insecure Direct Object Reference in Fastapi with Dynamodb

Insecure Direct Object Reference in Fastapi with Dynamodb — 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 DynamoDB primary key or sort key—and allows an authenticated subject to access or modify that object without verifying authorization. In a FastAPI application that uses DynamoDB, this commonly arises when route parameters (e.g., user_id or document_id) are passed directly into DynamoDB requests without confirming that the requesting user has permission to access the corresponding item.

Consider a FastAPI endpoint that retrieves a user profile using a path parameter user_id. If the endpoint performs a GetItem or Query on a DynamoDB table using user_id as the key but does not confirm that the authenticated subject owns that user_id, the endpoint becomes vulnerable to IDOR. An attacker who can obtain or guess another user’s ID can issue requests and read or influence other users’ data. This risk is compounded because DynamoDB responses do not inherently enforce ownership; it is the application’s responsibility to validate access controls for each request.

Because FastAPI often deserializes path, query, or body parameters into Pydantic models, developers may mistakenly trust these values as safe identifiers. If authorization logic is omitted or applied inconsistently—such as checking group membership but not matching the specific item’s ownership—an IDOR vulnerability exists. For example, an endpoint that supports tenant-aware operations must ensure that a tenant_id from the path is validated against the DynamoDB item’s tenant attribute, rather than relying on network-level isolation or assuming that a list query is inherently safe.

IDOR is frequently identified by middleBrick in the BOLA/IDOR security check, which examines whether object-level authorization is enforced for direct object references. When scanning a FastAPI service backed by DynamoDB, middleBrick tests unauthenticated and authenticated scenarios to detect endpoints where object references can be manipulated to access unauthorized data. Findings include references to the specific DynamoDB key schema and guidance to enforce ownership or tenant checks before performing GetItem, Query, or UpdateItem operations.

Dynamodb-Specific Remediation in Fastapi — concrete code fixes

To remediate IDOR with DynamoDB in FastAPI, enforce authorization checks that tie each DynamoDB request to the requesting subject. This includes validating that the authenticated user’s ID matches the item’s ownership attribute, applying tenant scoping, and avoiding broad or indirect queries that can expose other users’ items.

Below are concrete, working examples using the AWS SDK for Python (Boto3) with FastAPI. They demonstrate how to safely retrieve and update items by ensuring the request subject is explicitly verified against the DynamoDB record before proceeding.

Example 1: Safe item retrieval with ownership check

In this pattern, the endpoint extracts both the authenticated subject (e.g., from a JWT or session) and the requested identifier from the path. It then queries the DynamoDB table using a composite key that includes the subject, ensuring that users can only access their own items.

from fastapi import FastAPI, Depends, HTTPException, status
from pydantic import BaseModel
import boto3
from botocore.exceptions import ClientError

app = FastAPI()
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table_name = 'user_profiles'

class UserProfile(BaseModel):
    user_id: str
    name: str
    email: str

def get_current_user_id() -> str:
    # Replace with your authentication logic (e.g., JWT verification)
    return "user-123"

@app.get('/profiles/{user_id}', response_model=UserProfile)
def get_profile(user_id: str, current_user_id: str = Depends(get_current_user_id)):
    if user_id != current_user_id:
        raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail='Access denied')
    table = dynamodb.Table(table_name)
    try:
        response = table.get_item(Key={'user_id': user_id})
    except ClientError as e:
        raise HTTPException(status_code=500, detail='Database error')
    item = response.get('Item')
    if item is None:
        raise HTTPException(status_code=404, detail='Profile not found')
    return UserProfile(**item)

Example 2: Scoped query with tenant ownership

When records are scoped by a tenant or group, include the tenant identifier both in the DynamoDB key design and in runtime checks. This prevents a subject from enumerating or modifying items belonging to other tenants.

from fastapi import FastAPI, Depends, HTTPException, status
from pydantic import BaseModel
import boto3
from botocore.exceptions import ClientError

app = FastAPI()
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table_name = 'tenant_documents'

class Document(BaseModel):
    tenant_id: str
    document_id: str
    content: str

def get_current_tenant_id() -> str:
    # Replace with your tenant resolution logic
    return "tenant-abc"

@app.get('/documents/{document_id}', response_model=Document)
def get_document(document_id: str, tenant_id: str = Depends(get_current_tenant_id)):
    table = dynamodb.Table(table_name)
    try:
        response = table.get_item(Key={'tenant_id': tenant_id, 'document_id': document_id})
    except ClientError as e:
        raise HTTPException(status_code=500, detail='Database error')
    item = response.get('Item')
    if item is None:
        raise HTTPException(status_code=404, detail='Document not found')
    return Document(**item)

General mitigation guidance

  • Always verify the requesting subject against the item’s ownership or tenant attributes before performing GetItem, Query, UpdateItem, or DeleteItem.
  • Design your DynamoDB key schema to include ownership context (e.g., composite keys with user_id as partition key) so that queries are naturally scoped.
  • Avoid using client-supplied identifiers as the sole means of object lookup; use them in combination with server-side subject context.
  • Apply the principle of least privilege to the IAM role used by FastAPI so that it cannot read or write items outside the intended scope.

middleBrick’s checks align with findings related to OWASP API Top 10 A01:2023 — Broken Object Level Authorization. By combining these code-level patterns with continuous scanning, you reduce the likelihood of IDOR-related data exposure in DynamoDB-backed FastAPI 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 middleBrick fix IDOR vulnerabilities in FastAPI and DynamoDB?
middleBrick detects and reports IDOR findings with severity, descriptions, and remediation guidance. It does not automatically fix or patch your code; you must apply the recommended remediations in your application.
How can I prevent IDOR when using DynamoDB key design in FastAPI?
Prevent IDOR by designing DynamoDB keys to include ownership context (e.g., user_id as partition key), enforcing authorization checks in FastAPI endpoints before GetItem/Query/UpdateItem, and validating that the authenticated subject matches the item’s ownership or tenant attributes on every request.