HIGH pii leakagefastapidynamodb

Pii Leakage in Fastapi with Dynamodb

Pii Leakage in Fastapi with Dynamodb — how this specific combination creates or exposes the vulnerability

A FastAPI service that uses Amazon DynamoDB can inadvertently expose personally identifiable information (PII) through a combination of application-level data handling and DynamoDB access patterns. PII leakage occurs when endpoints return entire DynamoDB items or overly broad query results without filtering sensitive fields, and when the API does not enforce field-level authorization or consistent encryption practices. For example, an endpoint like /users/{user_id} might call get_item on a DynamoDB table that stores profile data including email, phone, and address, and then return the full item to the client. If the route does not explicitly omit or redact sensitive keys, the response becomes a direct source of PII leakage.

DynamoDB-specific factors that contribute to risk include permissive IAM policies that allow broader read access than intended, sparse attribute-level permissions in the application layer, and the use of sparse projections in queries that pull more attributes than necessary. When FastAPI merges raw DynamoDB responses into JSON-serializable dictionaries, any PII present is automatically exposed to the client unless the code explicitly prunes or masks it. Additionally, features like DynamoDB Streams can propagate sensitive data to downstream consumers (e.g., analytics or logging systems) if those consumers are not configured to filter or encrypt PII. Misconfigured encryption settings, such as disabling encryption at rest or failing to enforce encryption in transit via HTTPS, can also increase the likelihood of exposure during data retrieval.

The 12 security checks in middleBrick test this combination by examining unauthenticated surfaces and OpenAPI specifications, identifying endpoints that return sensitive data without sufficient authorization or input constraints. For instance, an OpenAPI schema that defines a 200 response model containing email and ssn without indicating redaction or conditional inclusion flags can be flagged for PII exposure. Runtime probes may validate that query results do not leak credentials or contact details, and whether rate limiting and property-level authorization are in place to prevent excessive data retrieval. This approach highlights how FastAPI route implementations and DynamoDB access patterns jointly determine whether PII is safely contained or unintentionally exposed.

Dynamodb-Specific Remediation in Fastapi — concrete code fixes

To mitigate PII leakage when using FastAPI with DynamoDB, implement explicit field filtering, secure IAM policies, and encryption enforcement. Below are concrete code examples that demonstrate secure patterns.

1. Retrieve only necessary attributes with ProjectionExpression

Use ProjectionExpression in get_item and query requests to limit DynamoDB responses to required, non-sensitive attributes. This reduces the data surface exposed to the API layer.

import boto3
from fastapi import FastAPI, HTTPException

app = FastAPI()
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('users')

@app.get('/users/{user_id}')
def get_user_public(user_id: str):
    response = table.get_item(
        Key={'user_id': user_id},
        ProjectionExpression='user_id, display_name, avatar_url'
    )
    item = response.get('Item')
    if item is None:
        raise HTTPException(status_code=404, detail='User not found')
    return item

2. Explicitly redact or rename sensitive fields before returning

When broader access is required, transform the item in FastAPI to remove or rename PII fields such as email and phone before serialization.

import boto3
from fastapi import FastAPI, HTTPException

app = FastAPI()
dynamodb = boto3.resource('dynamodb', region_name='us-east-1')
table = dynamodb.Table('users')

def sanitize_user_item(item: dict) -> dict:
    return {
        'user_id': item.get('user_id'),
        'display_name': item.get('display_name'),
        'avatar_url': item.get('avatar_url')
        # email, phone, and ssn are intentionally omitted
    }

@app.get('/users/{user_id}')
def get_user_sanitized(user_id: str):
    response = table.get_item(Key={'user_id': user_id})
    item = response.get('Item')
    if item is None:
        raise HTTPException(status_code=404, detail='User not found')
    return sanitize_user_item(item)

3. Enforce encryption in transit and at rest via resource policies and client configuration

Ensure that the DynamoDB client uses HTTPS and that the table enforces encryption at rest. While infrastructure settings are outside FastAPI, the application can require secure endpoints and validate responses.

import boto3
from botocore.exceptions import ClientError
from fastapi import FastAPI

app = FastAPI()

def get_secure_dynamodb_client():
    return boto3.client(
        'dynamodb',
        region_name='us-east-1',
        endpoint_url='https://dynamodb.us-east-1.amazonaws.com'  # HTTPS enforced
    )

@app.get('/health')
def check_dynamodb_encryption():
    client = get_secure_dynamodb_client()
    try:
        # A lightweight call to verify connectivity and TLS
        client.list_tables(Limit=1)
        return {'status': 'secure'}
    except ClientError as e:
        raise HTTPException(status_code=503, detail=f'DynamoDB connection error: {e}')

4. Apply least-privilege IAM via role-specific policies

Define IAM policies that grant only the necessary actions on specific resources. FastAPI assumes the runtime environment provides a properly scoped role or user, avoiding broad read permissions on user tables.

# Example IAM policy (conceptual, not code executed by FastAPI)
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "dynamodb:GetItem",
                "dynamodb:Query"
            ],
            "Resource": "arn:aws:dynamodb:us-east-1:123456789012:table/users",
            "Condition": {
                "ForAllValues:StringEquals": {
                    "dynamodb:LeadingKeys": ["${cognito-identity.amazonaws.com:sub}"]
                }
            }
        }
    ]
}

By combining these practices—field projection, explicit redaction, secure client configuration, and least-privilege access—you significantly reduce the risk of PII leakage in FastAPI applications backed by DynamoDB.

Related CWEs: dataExposure

CWE IDNameSeverity
CWE-200Exposure of Sensitive Information HIGH
CWE-209Error Information Disclosure MEDIUM
CWE-213Exposure of Sensitive Information Due to Incompatible Policies HIGH
CWE-215Insertion of Sensitive Information Into Debugging Code MEDIUM
CWE-312Cleartext Storage of Sensitive Information HIGH
CWE-359Exposure of Private Personal Information (PII) HIGH
CWE-522Insufficiently Protected Credentials CRITICAL
CWE-532Insertion of Sensitive Information into Log File MEDIUM
CWE-538Insertion of Sensitive Information into Externally-Accessible File HIGH
CWE-540Inclusion of Sensitive Information in Source Code HIGH

Frequently Asked Questions

Does middleBrick fix PII leakage findings automatically?
No. middleBrick detects and reports PII leakage findings with remediation guidance. It does not automatically fix, patch, block, or remediate issues.
How often should I scan FastAPI services that use DynamoDB?
Use continuous monitoring in the Pro plan to schedule regular scans, and integrate the GitHub Action in CI/CD to fail builds if risk scores drop. Frequency should align with deployment cadence and data sensitivity.