Skip to content

fix(fastapi): Stop eagerly consuming request bodies for streamed spans#6286

Merged
alexander-alderman-webb merged 31 commits into
masterfrom
webb/fastapi/request-body-async
Jun 9, 2026
Merged

fix(fastapi): Stop eagerly consuming request bodies for streamed spans#6286
alexander-alderman-webb merged 31 commits into
masterfrom
webb/fastapi/request-body-async

merge master

631afbf
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden: find-bugs completed Jun 9, 2026 in 22m 36s

2 issues

find-bugs: Found 2 issues (1 high, 1 low)

High

Cached request body (form/JSON) written to streamed span attributes without PII scrubbing - `tests/integrations/fastapi/test_fastapi.py:233`

_get_cached_request_body_attribute in starlette.py serializes the cached request body (request._json or request._form) directly with json.dumps and the result is stored on the streamed span via current_span._segment.set_attribute(SPANDATA.HTTP_REQUEST_BODY_DATA, ...) in both starlette.py (_wrap_async_handler) and fastapi.py (_wrap_async_handler). Unlike the event path, which runs through the Sentry scrubbing pipeline (so a password field becomes [Filtered]), the span-attribute path applies no denylist/redaction. Sensitive fields such as passwords therefore land in plaintext in span data. This is a known limitation acknowledged in the PR/test comments (scrubbing deferred to future before_send_span hooks), but it ships in this state.

Low

`_serialize_request_body_data` is now dead code after its only caller was removed - `sentry_sdk/integrations/starlette.py:255`

The _set_request_body_data_on_streaming_segment function deleted in this diff was the only caller of _serialize_request_body_data; the helper now goes unused and should be removed too.


⏱ 21m 34s · 2.0M in / 144.7k out · $3.88

Annotations

Check failure on line 233 in tests/integrations/fastapi/test_fastapi.py

See this annotation in the file changed.

@sentry-warden sentry-warden / warden: find-bugs

Cached request body (form/JSON) written to streamed span attributes without PII scrubbing

`_get_cached_request_body_attribute` in starlette.py serializes the cached request body (`request._json` or `request._form`) directly with `json.dumps` and the result is stored on the streamed span via `current_span._segment.set_attribute(SPANDATA.HTTP_REQUEST_BODY_DATA, ...)` in both starlette.py (`_wrap_async_handler`) and fastapi.py (`_wrap_async_handler`). Unlike the event path, which runs through the Sentry scrubbing pipeline (so a `password` field becomes `[Filtered]`), the span-attribute path applies no denylist/redaction. Sensitive fields such as passwords therefore land in plaintext in span data. This is a known limitation acknowledged in the PR/test comments (scrubbing deferred to future `before_send_span` hooks), but it ships in this state.