From 666e6fbccef4436deb7743b7a883b157d1996ef1 Mon Sep 17 00:00:00 2001 From: Erica Pisani Date: Thu, 4 Jun 2026 08:37:59 -0400 Subject: [PATCH 1/4] fix(asgi): Gate query string and client IP behind send_default_pii Move http.query and client.address attribute collection inside the should_send_default_pii() check so sensitive values are not captured by default. Fixes PY-2514 Fixes #6499 --- sentry_sdk/integrations/_asgi_common.py | 9 +++++---- tests/integrations/asgi/test_asgi.py | 13 ++++++++++--- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/sentry_sdk/integrations/_asgi_common.py b/sentry_sdk/integrations/_asgi_common.py index 0aa88b100d..eafce0efaa 100644 --- a/sentry_sdk/integrations/_asgi_common.py +++ b/sentry_sdk/integrations/_asgi_common.py @@ -121,6 +121,7 @@ def _get_request_attributes(asgi_scope: "Any") -> "dict[str, Any]": for header, value in headers.items(): attributes[f"http.request.header.{header.lower()}"] = value + if should_send_default_pii(): query = _get_query(asgi_scope) if query: attributes["http.query"] = query @@ -129,9 +130,9 @@ def _get_request_attributes(asgi_scope: "Any") -> "dict[str, Any]": asgi_scope, "http" if ty == "http" else "ws", headers.get("host") ) - client = asgi_scope.get("client") - if client and should_send_default_pii(): - ip = _get_ip(asgi_scope) - attributes["client.address"] = ip + client = asgi_scope.get("client") + if client: + ip = _get_ip(asgi_scope) + attributes["client.address"] = ip return attributes diff --git a/tests/integrations/asgi/test_asgi.py b/tests/integrations/asgi/test_asgi.py index dd0bc8b59d..50d3606d98 100644 --- a/tests/integrations/asgi/test_asgi.py +++ b/tests/integrations/asgi/test_asgi.py @@ -164,6 +164,10 @@ def test_invalid_transaction_style(asgi3_app): @pytest.mark.asyncio +@pytest.mark.parametrize( + "should_send_pii", + [True, False], +) @pytest.mark.parametrize( "span_streaming", [True, False], @@ -174,9 +178,10 @@ async def test_capture_transaction( capture_events, capture_items, span_streaming, + should_send_pii, ): sentry_init( - send_default_pii=True, + send_default_pii=should_send_pii, traces_sample_rate=1.0, _experiments={ "trace_lifecycle": "stream" if span_streaming else "static", @@ -203,16 +208,18 @@ async def test_capture_transaction( assert span["attributes"]["sentry.span.source"] == "url" assert span["attributes"]["sentry.op"] == "http.server" - assert span["attributes"]["url.full"] == "http://localhost/some_url" assert span["attributes"]["network.protocol.name"] == "http" assert span["attributes"]["http.request.method"] == "GET" - assert span["attributes"]["http.query"] == "somevalue=123" assert span["attributes"]["http.request.header.host"] == "localhost" assert span["attributes"]["http.request.header.remote-addr"] == "127.0.0.1" assert ( span["attributes"]["http.request.header.user-agent"] == "ASGI-Test-Client" ) + if should_send_pii: + assert span["attributes"]["url.full"] == "http://localhost/some_url" + assert span["attributes"]["http.query"] == "somevalue=123" + else: (transaction_event,) = events From adc69e9a9ed4ab1d11db01f565f6a640ba92d5ac Mon Sep 17 00:00:00 2001 From: Erica Pisani Date: Thu, 4 Jun 2026 08:55:53 -0400 Subject: [PATCH 2/4] fix --- sentry_sdk/integrations/_asgi_common.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/sentry_sdk/integrations/_asgi_common.py b/sentry_sdk/integrations/_asgi_common.py index eafce0efaa..1229e0cc24 100644 --- a/sentry_sdk/integrations/_asgi_common.py +++ b/sentry_sdk/integrations/_asgi_common.py @@ -121,18 +121,18 @@ def _get_request_attributes(asgi_scope: "Any") -> "dict[str, Any]": for header, value in headers.items(): attributes[f"http.request.header.{header.lower()}"] = value - if should_send_default_pii(): - query = _get_query(asgi_scope) - if query: - attributes["http.query"] = query + if should_send_default_pii(): + query = _get_query(asgi_scope) + if query: + attributes["http.query"] = query - attributes["url.full"] = _get_url( - asgi_scope, "http" if ty == "http" else "ws", headers.get("host") - ) + attributes["url.full"] = _get_url( + asgi_scope, "http" if ty == "http" else "ws", headers.get("host") + ) - client = asgi_scope.get("client") - if client: - ip = _get_ip(asgi_scope) - attributes["client.address"] = ip + client = asgi_scope.get("client") + if client and should_send_default_pii(): + ip = _get_ip(asgi_scope) + attributes["client.address"] = ip return attributes From eb14dd061bd6f5cc9813d8580e5c78aec8a55e27 Mon Sep 17 00:00:00 2001 From: Erica Pisani Date: Wed, 10 Jun 2026 10:55:09 -0400 Subject: [PATCH 3/4] Update the value set on to include the query string --- sentry_sdk/integrations/_asgi_common.py | 4 +++- tests/integrations/asgi/test_asgi.py | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/sentry_sdk/integrations/_asgi_common.py b/sentry_sdk/integrations/_asgi_common.py index 1229e0cc24..9cd9ca6ac9 100644 --- a/sentry_sdk/integrations/_asgi_common.py +++ b/sentry_sdk/integrations/_asgi_common.py @@ -126,9 +126,11 @@ def _get_request_attributes(asgi_scope: "Any") -> "dict[str, Any]": if query: attributes["http.query"] = query - attributes["url.full"] = _get_url( + url_without_query_string = _get_url( asgi_scope, "http" if ty == "http" else "ws", headers.get("host") ) + query_string = _get_query(asgi_scope) + attributes["url.full"] = f"{url_without_query_string}?{query_string}" client = asgi_scope.get("client") if client and should_send_default_pii(): diff --git a/tests/integrations/asgi/test_asgi.py b/tests/integrations/asgi/test_asgi.py index 50d3606d98..b6c4705ea3 100644 --- a/tests/integrations/asgi/test_asgi.py +++ b/tests/integrations/asgi/test_asgi.py @@ -217,7 +217,10 @@ async def test_capture_transaction( ) if should_send_pii: - assert span["attributes"]["url.full"] == "http://localhost/some_url" + assert ( + span["attributes"]["url.full"] + == "http://localhost/some_url?somevalue=123" + ) assert span["attributes"]["http.query"] == "somevalue=123" else: From a792df4a7217bb94f5f3e7e1edc57c8e7f1f3e9d Mon Sep 17 00:00:00 2001 From: Erica Pisani Date: Wed, 10 Jun 2026 11:04:45 -0400 Subject: [PATCH 4/4] . --- sentry_sdk/integrations/_asgi_common.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/_asgi_common.py b/sentry_sdk/integrations/_asgi_common.py index 9cd9ca6ac9..bb44896a04 100644 --- a/sentry_sdk/integrations/_asgi_common.py +++ b/sentry_sdk/integrations/_asgi_common.py @@ -130,7 +130,11 @@ def _get_request_attributes(asgi_scope: "Any") -> "dict[str, Any]": asgi_scope, "http" if ty == "http" else "ws", headers.get("host") ) query_string = _get_query(asgi_scope) - attributes["url.full"] = f"{url_without_query_string}?{query_string}" + attributes["url.full"] = ( + f"{url_without_query_string}?{query_string}" + if query_string is not None + else url_without_query_string + ) client = asgi_scope.get("client") if client and should_send_default_pii():