Request Smuggling in Fastapi with Cockroachdb
Request Smuggling in Fastapi with Cockroachdb — how this specific combination creates or exposes the vulnerability
Request smuggling is an application-layer attack that exploits discrepancies in how a server parses the end of a message body versus how a backend interprets message framing. When Fastapi is placed behind a proxy or load balancer and uses Cockroachdb as the data layer, the risk is not that Cockroachdb introduces smuggling, but that the request lifecycle—parsing headers, routing, and body consumption—can be misaligned if the framework and proxy handle Content-Length or Transfer-Encoding differently.
In Fastapi, endpoints typically receive request bodies as parsed models (e.g., Pydantic). If a request with ambiguous or conflicting Content-Length and chunked Transfer-Encoding reaches the framework, the proxy might consume the body while Fastapi expects additional data, or vice versa. This can cause request splitting, where two requests are merged into one stream. Because Cockroachdb drivers in Fastapi often stream or buffer query parameters and body content for large payloads, the mismatch may surface as inconsistent transaction states or unexpected parameter handling rather than a direct protocol violation. Attackers can leverage this to smuggle requests into backend services, bypassing intended routing or authentication checks, and potentially reaching database operations that should have been isolated.
The unauthenticated attack surface tested by middleBrick includes header parsing and body handling across the request path. A Fastapi service using Cockroachdb with SQLAlchemy or asyncpg may expose subtle timing or error-difference channels when smuggling attempts cause partial commits or aborts. While Cockroachdb itself does not parse HTTP, the way Fastapi binds incoming data to database transactions can amplify the impact: a smuggled request might execute under an unintended tenant context or with elevated permissions if routing logic is bypassed. middleBrick’s checks for BOLA/IDOR and Property Authorization can surface these inconsistencies by observing whether different users can access or modify the same database resources through manipulated request boundaries.
To detect this during a scan, middleBrick runs parallel checks including Input Validation and Unsafe Consumption, observing how Fastapi deserializes bodies and how responses differ when smuggling-like patterns are injected. The scanner does not assume internal architecture but observes behavior: for example, a 200 response to a second smuggled request where a 400 or 403 is expected indicates a routing or parsing weakness that may intersect with Cockroachdb transaction handling.
Cockroachdb-Specific Remediation in Fastapi — concrete code fixes
Remediation focuses on ensuring consistent message parsing and strict separation of request contexts before any Cockroachdb interaction. Use explicit body handling and avoid relying on automatic parsing when the request pipeline includes proxies that may modify headers.
1. Explicit body reading before Pydantic parsing
Read the raw body once and validate structure before passing to Cockroachdb transactions. This prevents double-consumption issues where a proxy and Fastapi framework interpret the body differently.
from fastapi import FastAPI, Request, HTTPException
import json
app = FastAPI()
@app.post("/users/{user_id}/transfer")
async def transfer_funds(user_id: str, request: Request):
raw_body = await request.body()
try:
data = json.loads(raw_body)
except json.JSONDecodeError:
raise HTTPException(status_code=400, detail="Invalid JSON")
# Validate required fields explicitly
if "amount" not in data or "target" not in data:
raise HTTPException(status_code=400, detail="Missing fields")
# Proceed to Cockroachdb with clean, parsed data
# db.execute(...) using data["amount"], data["target"], user_id
return {"status": "ok"}
2. Enforce consistent Transfer-Encoding and disable chunked parsing when necessary
Configure your proxy to use a single, canonical framing method (typically Content-Length) and ensure Fastapi does not attempt to interpret chunked bodies in a way that conflicts with upstream expectations. In code, avoid relying on streaming body consumers when operating on sensitive transactional operations.
3. Isolate database sessions per request and validate tenant context
When using Cockroachdb, bind each request to a dedicated session and verify tenant ownership before executing queries. This limits the impact if smuggling alters perceived identity.
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from fastapi import Depends
DATABASE_URL = "cockroachdb://root@cockroachdb-host:26257/defaultdb?sslmode=require"
engine = create_async_engine(DATABASE_URL, echo=False)
AsyncSessionLocal = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
def get_db():
async def _get_db(request):
async with AsyncSessionLocal() as session:
try:
# Example: enforce tenant scoping
tenant_id = request.state.tenant_id # set after auth
# db query using tenant_id to scope data
yield session
finally:
await session.close()
return _get_db
@app.post("/accounts/{account_id}/update")
async def update_account(account_id: int, db: AsyncSession = Depends(get_db)):
# Query with tenant-aware filter
result = await db.execute(
"SELECT id FROM accounts WHERE id = :id AND tenant_id = :tenant",
{"id": account_id, "tenant": db_tenant}
)
if not result.scalar_one_or_none():
raise HTTPException(status_code=404, detail="Not found")
# Safe update within the isolated session
return {"updated": True}
4. Use middleware to normalize headers and reject ambiguous requests
Add a FastAPI middleware that checks for conflicting Transfer-Encoding and Content-Length headers before routing to endpoints that interact with Cockroachdb.
from fastapi import Request
from starlette.middleware.base import BaseHTTPMiddleware
class SmugglingDefenseMiddleware(BaseHTTPMiddleware):
async def dispatch(self, request: Request, call_next):
te = request.headers.get("transfer-encoding", "")
cl = request.headers.get("content-length", "")
if te and cl:
# Reject requests that mix framing mechanisms
raise HTTPException(status_code=400, detail="Conflicting transfer mechanisms")
response = await call_next(request)
return response
app.add_middleware(SmugglingDefenseMiddleware)
Frequently Asked Questions
Does middleBrick test for request smuggling in Fastapi with Cockroachdb?
Can I use the CLI to scan my Fastapi service that uses Cockroachdb?
middlebrick scan <url> from your terminal to scan your Fastapi endpoint. The output can be used in scripts or integrated into CI/CD with the GitHub Action to fail builds if the risk score drops below your chosen threshold.