From e4c8f5e428988dfced0547df1e5db3a1ebcdce7f Mon Sep 17 00:00:00 2001 From: Erica Pisani Date: Thu, 25 Jun 2026 13:09:36 -0400 Subject: [PATCH] fix(sanic): Gate url.full, url.path, and http.query behind send_default_pii Move url.full, url.path, and http.query span attributes behind the send_default_pii flag to avoid leaking PII in Sanic request spans. Consistent with the same fix applied to aiohttp, wsgi, and asgi. Co-Authored-By: Claude Sonnet 4.6 --- sentry_sdk/integrations/sanic.py | 8 +++++--- tests/integrations/sanic/test_sanic.py | 18 +++++++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/sentry_sdk/integrations/sanic.py b/sentry_sdk/integrations/sanic.py index 468a1323a8..908fceb0cf 100644 --- a/sentry_sdk/integrations/sanic.py +++ b/sentry_sdk/integrations/sanic.py @@ -380,10 +380,12 @@ def _get_request_attributes(request: "Request") -> "Dict[str, Any]": urlparts = urlsplit(request.url) - if urlparts.query: - attributes[SPANDATA.HTTP_QUERY] = urlparts.query + if should_send_default_pii(): + attributes[SPANDATA.URL_FULL] = request.url + attributes["url.path"] = urlparts.path - attributes[SPANDATA.URL_FULL] = request.url + if urlparts.query: + attributes[SPANDATA.HTTP_QUERY] = urlparts.query if urlparts.scheme: attributes[SPANDATA.NETWORK_PROTOCOL_NAME] = urlparts.scheme diff --git a/tests/integrations/sanic/test_sanic.py b/tests/integrations/sanic/test_sanic.py index 2e077621da..703da52bc1 100644 --- a/tests/integrations/sanic/test_sanic.py +++ b/tests/integrations/sanic/test_sanic.py @@ -363,6 +363,7 @@ def __init__( @pytest.mark.skipif( not PERFORMANCE_SUPPORTED, reason="Performance not supported on this Sanic version" ) +@pytest.mark.parametrize("send_pii", [True, False]) @pytest.mark.parametrize("span_streaming", [True, False]) @pytest.mark.parametrize( "test_config", @@ -424,6 +425,7 @@ def test_transactions( capture_events: "Any", capture_items: "Any", span_streaming: bool, + send_pii: bool, ) -> None: if span_streaming and not test_config.streaming_compatible: pytest.skip("unsampled_statuses is not supported in span streaming mode") @@ -432,6 +434,7 @@ def test_transactions( sentry_init( integrations=[SanicIntegration(*test_config.integration_args)], traces_sample_rate=1.0, + send_default_pii=send_pii, _experiments={"trace_lifecycle": "stream" if span_streaming else "static"}, ) @@ -469,9 +472,6 @@ def test_transactions( attrs = segment["attributes"] assert attrs["http.request.method"] == "GET" - assert attrs["url.full"].endswith(test_config.url) - if "?" in test_config.url: - assert attrs["http.query"] == test_config.url.split("?", 1)[1] assert attrs["network.protocol.name"] == "http" header_keys = { key[len("http.request.header.") :] @@ -483,6 +483,18 @@ def test_transactions( assert segment["status"] == ( "error" if test_config.expected_status >= 400 else "ok" ) + + if send_pii: + assert attrs["url.full"].endswith(test_config.url) + assert attrs["url.path"] == test_config.url.split("?")[0] + if "?" in test_config.url: + assert attrs["http.query"] == test_config.url.split("?", 1)[1] + + else: + assert "url.full" not in attrs + assert "url.path" not in attrs + assert "http.query" not in attrs + else: # Extract the transaction events by inspecting the event types. We should at most have 1 transaction event. transaction_events = [