Skip to content

fix(stdlib): Gate url.full and http.query behind send_default_pii#6666

Merged
ericapisani merged 5 commits into
masterfrom
py-2557-gate-url-full-behind-pii-stdlib
Jun 26, 2026
Merged

fix(stdlib): Gate url.full and http.query behind send_default_pii#6666
ericapisani merged 5 commits into
masterfrom
py-2557-gate-url-full-behind-pii-stdlib

Conversation

@ericapisani

@ericapisani ericapisani commented Jun 25, 2026

Copy link
Copy Markdown
Member

url.full, url.query, and url.fragment span attributes set by the stdlib (httplib) integration are now gated behind send_default_pii, consistent with the same fix already applied to the aiohttp and wsgi integrations. These attributes can contain sensitive query parameters or path fragments, so they should only be captured when the user has explicitly opted in.

http.fragment on the legacy span data path is unconditionally omitted since fragments are never sent to the server and carry no useful diagnostic value regardless of PII setting.

Fixes #PY-2557
Fixes #6665

Gate URL_FULL, URL_QUERY, and HTTP_QUERY span attributes behind
send_default_pii in the stdlib (httplib) integration, consistent with
the aiohttp and wsgi integrations. Tests are updated to pass
send_default_pii=True where they assert on those attributes, and the
proxy tunnel test is expanded to cover both pii=True and pii=False.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@linear-code

linear-code Bot commented Jun 25, 2026

Copy link
Copy Markdown

PY-2557

@ericapisani ericapisani changed the title fix(stdlib): Gate url.full and http.query behind send_default_pii fix(stdlib): Gate url.full and http.query behind send_default_pii in stdlib Jun 25, 2026
@ericapisani ericapisani changed the title fix(stdlib): Gate url.full and http.query behind send_default_pii in stdlib fix(stdlib): Gate url.full and http.query behind send_default_pii Jun 25, 2026
Comment thread sentry_sdk/integrations/stdlib.py
@github-actions

github-actions Bot commented Jun 25, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

89965 passed | ⏭️ 6240 skipped | Total: 96205 | Pass Rate: 93.51% | Execution Time: 320m 7s

📊 Comparison with Base Branch

Metric Change
Total Tests 📈 +60
Passed Tests 📈 +60
Failed Tests
Skipped Tests

All tests are passing successfully.

✅ Patch coverage is 100.00%. Project has 2394 uncovered lines.
✅ Project coverage is 89.93%. Comparing base (base) to head (head).

Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    89.93%    89.93%        —%
==========================================
  Files          192       192         —
  Lines        23784     23784         —
  Branches      8210      8210         —
==========================================
+ Hits         21389     21390        +1
- Misses        2395      2394        -1
- Partials      1342      1340        -2

Generated by Codecov Action

@ericapisani ericapisani marked this pull request as ready for review June 25, 2026 18:54
@ericapisani ericapisani requested a review from a team as a code owner June 25, 2026 18:54

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 2 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 0f7cab6. Configure here.

span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)
span.set_data("url", parsed_url.url)
span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query)
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legacy spans skip PII gate

High Severity

The streamed-span branch only sets url.full, url.query, and url.fragment when should_send_default_pii() is true, but the non-streaming branch still writes url and http.query whenever parsed_url is set. With send_default_pii disabled, sensitive query strings still land on spans and httplib breadcrumbs copied from span data.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0f7cab6. Configure here.


span.set_data(SPANDATA.HTTP_METHOD, method)
if parsed_url is not None:
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Legacy fragment not omitted

Low Severity

The PR states http.fragment on the legacy span data path is unconditionally omitted, yet the non-streaming branch still calls span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment) whenever a URL is parsed.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 0f7cab6. Configure here.

Comment on lines 143 to 146
if parsed_url is not None:
span.set_data(SPANDATA.HTTP_FRAGMENT, parsed_url.fragment)
span.set_data("url", parsed_url.url)
span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The non-streaming code path unconditionally adds HTTP_QUERY to spans, ignoring the send_default_pii setting and potentially leaking sensitive data in query parameters.
Severity: HIGH

Suggested Fix

Add the if should_send_default_pii(): check around the span.set_data(SPANDATA.HTTP_QUERY, parsed_url.query) call in the else block to ensure query parameters are only captured when PII sending is enabled, mirroring the logic in the streaming 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/stdlib.py#L143-L146

Potential issue: The legacy code path for creating non-streaming spans unconditionally
includes `HTTP_QUERY` data. The code correctly checks `should_send_default_pii()` before
adding query parameters for streaming spans, but the `else` block for non-streaming
spans lacks this check. It directly calls `span.set_data(SPANDATA.HTTP_QUERY,
parsed_url.query)`, meaning query parameters are always captured for non-streaming HTTP
client requests, even when `send_default_pii` is `False`. This can lead to the leakage
of sensitive information contained in URL query strings.

Did we get this right? 👍 / 👎 to inform future reviews.

@ericapisani ericapisani merged commit 7ce81ec into master Jun 26, 2026
270 of 272 checks passed
@ericapisani ericapisani deleted the py-2557-gate-url-full-behind-pii-stdlib branch June 26, 2026 11:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Gate url.full behind the PII flag in stdlib

2 participants