fix(fastapi): Stop eagerly consuming request bodies for streamed spans#6286
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
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.