ref(integrations): route HTTP header filtering through data collection config#6788
ref(integrations): route HTTP header filtering through data collection config#6788ericapisani wants to merge 21 commits into
Conversation
…n config `_filter_headers` previously used a hardcoded sensitive-header tuple and a `send_default_pii`/`use_annotated_value` toggle. It now delegates to `_apply_key_value_collection_filtering` from `sentry_sdk.data_collection`, so header scrubbing respects the new `data_collection.http_headers.request` allowlist/denylist/off configuration. Cookie and set-cookie headers are always redacted regardless of mode. Drops the now-unused `use_annotated_value` parameter from all call sites. Work to scrub cookies in a more granular way will be tackled as part of PY-2581/#6741. Fixes PY-2584 Fixes #6744
Codecov Results 📊✅ 92149 passed | ⏭️ 6302 skipped | Total: 98451 | Pass Rate: 93.6% | Execution Time: 314m 21s 📊 Comparison with Base Branch
➖ Removed Tests (1)View removed tests
All tests are passing successfully. ✅ Patch coverage is 100.00%. Project has 2478 uncovered lines. Files with missing lines (1)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
+ Coverage 89.68% 89.69% +0.01%
==========================================
Files 193 193 —
Lines 24004 24045 +41
Branches 8340 8370 +30
==========================================
+ Hits 21527 21567 +40
- Misses 2477 2478 +1
- Partials 1386 1389 +3Generated by Codecov Action |
… _experiments property in the client
…still being needed for the url attribute
…ures The new lambda_functions_with_embedded_sdk fixture directories were missing the .gitignore that the other fixtures use to keep everything except index.py untracked. As a result, certifi and urllib3 packages installed by the test setup got committed, and ruff failed CI linting against them since they're unmodified third-party code. Add the missing .gitignore to each new fixture directory and remove the committed vendored packages; they are regenerated automatically at test time via `uv pip install --target`.
| headers = _get_headers(asgi_scope) | ||
|
|
||
| request_data["headers"] = _filter_headers( | ||
| headers, | ||
| use_annotated_value=False, |
There was a problem hiding this comment.
This change was done because when if the headers are filtered with "allowlist" and no terms are provided, and the "host" header is present, then the constructed URL in _get_url below would contain [Filtered] within the URL.
Doing this ensures that it gets filtered from the headers to respect data collection, but still correctly appears in the url
…n config `_filter_headers` previously used a hardcoded sensitive-header tuple and a `send_default_pii`/`use_annotated_value` toggle. It now delegates to `_apply_key_value_collection_filtering` from `sentry_sdk.data_collection`, so header scrubbing respects the new `data_collection.http_headers.request` allowlist/denylist/off configuration. Cookie and set-cookie headers are always redacted regardless of mode. Drops the now-unused `use_annotated_value` parameter from all call sites. Work to scrub cookies in a more granular way will be tackled as part of PY-2581/#6741. Fixes PY-2584 Fixes #6744
… _experiments property in the client
…still being needed for the url attribute
…ures The new lambda_functions_with_embedded_sdk fixture directories were missing the .gitignore that the other fixtures use to keep everything except index.py untracked. As a result, certifi and urllib3 packages installed by the test setup got committed, and ruff failed CI linting against them since they're unmodified third-party code. Add the missing .gitignore to each new fixture directory and remove the committed vendored packages; they are regenerated automatically at test time via `uv pip install --target`.
951c408 to
d717172
Compare
…ntry/sentry-python into py-2584-update-wsgi-filter-headers
The streaming path no longer emits a client span when there is no current span (#6810), so unpack only the server span.
|
|
||
|
|
||
| def _map_from_send_default_pii( |
There was a problem hiding this comment.
Bug: The _filter_headers function unconditionally redacts Cookie and Set-Cookie headers, ignoring the user's data_collection allowlist configuration and preventing cookie capture.
Severity: MEDIUM
Suggested Fix
Remove the hardcoded redaction loop for Cookie and Set-Cookie headers from the _filter_headers function. The _apply_key_value_collection_filtering function should be the sole authority for filtering based on the user's configuration. If cookies need special default handling, they should be added to the _SENSITIVE_DENYLIST so users can override the behavior via the allowlist.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: sentry_sdk/data_collection.py#L136-L138
Potential issue: The `_filter_headers` function unconditionally redacts `Cookie` and
`Set-Cookie` headers, even when a user explicitly includes them in the
`data_collection.http_headers.request` allowlist. While the initial filtering step
correctly respects the allowlist, a subsequent hardcoded loop overwrites the cookie
values with `SENSITIVE_DATA_SUBSTITUTE`. This behavior is confirmed by a test case which
states that cookies are "always redacted...even when explicitly allowlisted". This
prevents users from capturing cookie values via the data collection API, silently
ignoring their explicit configuration and creating inconsistent behavior compared to
other allowlisted headers.
Also affects:
sentry_sdk/integrations/_wsgi_common.pytests/integrations/wsgi/test_wsgi.py
|
|
||
| filtered = _apply_key_value_collection_filtering( | ||
| items=headers, | ||
| behaviour=data_collection_configuration["http_headers"]["request"], | ||
| ) | ||
|
|
||
| for key in filtered: | ||
| if isinstance(key, str) and key.lower() in ("cookie", "set-cookie"): | ||
| filtered[key] = SENSITIVE_DATA_SUBSTITUTE | ||
|
|
||
| return { | ||
| k: (v if k.upper().replace("-", "_") not in SENSITIVE_HEADERS else substitute) | ||
| for k, v in headers.items() | ||
| } | ||
| return filtered |
There was a problem hiding this comment.
Bug: The _filter_headers function ignores the use_annotated_value parameter in its data collection path, leading to inconsistent redaction of sensitive headers compared to the legacy path.
Severity: MEDIUM
Suggested Fix
Modify the data collection path within _filter_headers to respect the use_annotated_value parameter. When use_annotated_value is True, use AnnotatedValue.removed_because_over_size_limit() as the substitute for filtered values instead of the hardcoded SENSITIVE_DATA_SUBSTITUTE. This will align the behavior of the data collection path with the legacy path.
Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: sentry_sdk/integrations/_wsgi_common.py#L212-L224
Potential issue: The `_filter_headers` function in `_wsgi_common.py` accepts a
`use_annotated_value` parameter which defaults to `True`. However, in the new code path
for data collection (lines 212-224), this parameter is ignored. When data collection is
enabled, sensitive headers are always replaced with the literal string `"[Filtered]"`.
This contrasts with the legacy path, where `use_annotated_value=True` causes sensitive
headers to be replaced with an `AnnotatedValue` object that includes metadata. This
inconsistency in the event payload structure can break downstream consumers that expect
the metadata from `AnnotatedValue` and affects multiple integrations (WSGI, Tornado,
Sanic, Quart, aiohttp) that rely on the default behavior.
Also affects:
sentry_sdk/integrations/wsgi.py:357sentry_sdk/integrations/tornado.py:279sentry_sdk/integrations/sanic.py:427sentry_sdk/integrations/quart.py:250sentry_sdk/integrations/aiohttp.py:470
_filter_headersfollows the legacysend_default_pii/use_annotated_valuebehaviour when the data collection behaviour is not enabled in_experiments.When data collection is enabled, it now delegates to
_apply_key_value_collection_filteringfromsentry_sdk.data_collection, so header scrubbing respects the newdata_collection.http_headers.requestallowlist/denylist/off configuration when data collection.Work to scrub cookies in a more granular way will be tackled as part of PY-2581/#6741.
Fixes PY-2584
Fixes #6744