Skip to content

feat(wsgi): Apply data_collection filtering to URL query strings#6827

Merged
ericapisani merged 35 commits into
masterfrom
py-2583-query-parameters
Jul 22, 2026
Merged

feat(wsgi): Apply data_collection filtering to URL query strings#6827
ericapisani merged 35 commits into
masterfrom
py-2583-query-parameters

Do not encode what is added to event/span attributes in order to conf…

fad0c9a
Select commit
Loading
Failed to load commit list.
@sentry/warden / warden completed Jul 16, 2026 in 0s

4 issues

Medium

Query string reconstruction drops percent-encoding, corrupting values - `sentry_sdk/data_collection.py:107-118`

parse_qs decodes percent-encoded query values, but reconstruction with f"{key}={item}" does not re-encode them, so characters like &, =, spaces, or % in the original values produce a malformed/ambiguous query string. Consider using urlencode() to re-encode the filtered pairs.

Also found at:

  • sentry_sdk/integrations/wsgi.py:379-384
Filtered query string is reassembled without URL-encoding, corrupting values and re-revealing scrubbed data - `sentry_sdk/integrations/wsgi.py:379-382`

_apply_data_collection_filtering_to_query_string parses the query string with parse_qs, which percent-decodes keys and values and splits on &/=, then rebuilds the string with plain f"{key}={item}" joined by & without re-encoding. Decoded values containing &/= split into extra apparent params, so a sensitive value that was scrubbed to [Filtered] under one key can reappear intact when it was embedded (URL-encoded) inside another kept key's value. Benign percent-encoded values (e.g. q=hello%20world) are also silently corrupted in the reported query string.

Also found at:

  • sentry_sdk/data_collection.py:107-116
client.address span attribute never set when data_collection is enabled - `sentry_sdk/integrations/wsgi.py:428-446`

When data_collection is configured, the if has_data_collection_enabled(...) branch is taken and never adds client.address, so client IP is silently dropped on spans even when user_info is enabled — a regression from the should_send_default_pii() path which set it.

Low

test_span_http_query_data_collection mutates parametrize input dict via pop - `tests/integrations/wsgi/test_wsgi.py:1277-1281`

init_kwargs.pop("_experiments", {}) mutates the shared parametrize param dict, so a re-run of the same param (e.g. via pytest-rerunfailures/flaky) would no longer see _experiments and silently exercise the wrong configuration (the data_collection config would be dropped and the assertion would check a different code path than intended).

4 skills analyzed
Skill Findings Duration Cost
security-review 0 7m 20s $1.23
code-review 1 4m 3s $1.84
find-bugs 3 6m 49s $3.13
skill-scanner 0 5m 18s $0.23

⏱ 23m 29s · 2.3M in / 140.3k out · $6.43