Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,10 @@ public class HttpTracingRequestInitializer implements HttpRequestInitializer {

@VisibleForTesting static final String HTTP_RPC_SYSTEM_NAME = "http";

private static final java.util.Set<String> REDACTED_QUERY_PARAMETERS =
com.google.common.collect.ImmutableSet.of(
"AWSAccessKeyId", "Signature", "sig", "X-Goog-Signature", "upload_id");

private final HttpRequestInitializer delegate;
private final Tracer tracer;

Expand All @@ -74,9 +78,7 @@ public void initialize(HttpRequest request) throws IOException {
// No active span to exists, skip instrumentation
return;
}
String host = request.getUrl().getHost();
int port = request.getUrl().getPort();
addInitialHttpAttributesToSpan(span, host, port);
addInitialHttpAttributesToSpan(span, request);

HttpResponseInterceptor originalInterceptor = request.getResponseInterceptor();
request.setResponseInterceptor(
Expand All @@ -99,14 +101,16 @@ public void initialize(HttpRequest request) throws IOException {
}

/** Add initial HTTP attributes to the existing active span */
private void addInitialHttpAttributesToSpan(Span span, String host, Integer port) {
private void addInitialHttpAttributesToSpan(Span span, HttpRequest request) {
BigQueryTelemetryTracer.addCommonAttributeToSpan(span);
span.setAttribute(BigQueryTelemetryTracer.RPC_SYSTEM_NAME, HTTP_RPC_SYSTEM_NAME);
String host = request.getUrl().getHost();
span.setAttribute(BigQueryTelemetryTracer.SERVER_ADDRESS, host);
if (port != null && port > 0) {
span.setAttribute(BigQueryTelemetryTracer.SERVER_PORT, port.longValue());
int port = request.getUrl().getPort();
if (port > 0) {
span.setAttribute(BigQueryTelemetryTracer.SERVER_PORT, (long) port);
}
// TODO add full sanitized url, url domain, request method
span.setAttribute(URL_FULL, getSanitizedUrl(request));
}

private static void addCommonResponseAttributesToSpan(
Expand Down Expand Up @@ -136,4 +140,22 @@ static void addResponseBodySizeToSpan(HttpResponse response, Span span) {
}
// TODO handle chunked responses
}

/* removes credentials from url */
Comment thread
ldetmer marked this conversation as resolved.
Outdated
private static String getSanitizedUrl(HttpRequest request) {
GenericUrl url = request.getUrl();
if (url == null) {
return null;
}
Comment thread
ldetmer marked this conversation as resolved.
Outdated
// redact credentials passes query params
GenericUrl clone = url.clone();
for (String key : clone.keySet()) {
if (REDACTED_QUERY_PARAMETERS.contains(key)) {
clone.put(key, "REDACTED");
}
}
String urlString = clone.build();
// redact credentials sent as part of the address
return urlString.replaceAll("^(https?://)[^@/]+@", "$1REDACTED:REDACTED@");
Comment thread
ldetmer marked this conversation as resolved.
Outdated
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
package com.google.cloud.bigquery.telemetry;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.Mockito.mock;
Expand Down Expand Up @@ -201,6 +203,48 @@ public void testUnsuccessfulResponseHandlerSetsErrorIfNoOriginal() throws IOExce
closeAndVerifySpanData(401, "GET", -1, -1);
}

@Test
public void testUrlQueryParametersAreRedacted() throws IOException {
HttpTransport transport = createTransport();
String urlWithQuery = BASE_URL + "?upload_id=secret_id&Signature=secret_sig&keep_me=ok";
HttpRequest request = buildGetRequest(transport, initializer, urlWithQuery);

HttpResponse response = request.execute();
response.disconnect();

spanScope.close();
parentSpan.end();

List<SpanData> spans = spanExporter.getFinishedSpanItems();
assertEquals(1, spans.size());
SpanData span = spans.get(0);
String urlFull = span.getAttributes().get(HttpTracingRequestInitializer.URL_FULL);

assertTrue(urlFull.contains("upload_id=REDACTED"));
assertTrue(urlFull.contains("Signature=REDACTED"));
assertTrue(urlFull.contains("keep_me=ok"));
}

@Test
public void testUrlCredentialsAreRedacted() throws IOException {
HttpTransport transport = createTransport();
String credUrl = "https://user:pass@bigquery.googleapis.com/bigquery/v2/projects/test/datasets";
HttpRequest request = buildGetRequest(transport, initializer, credUrl);

HttpResponse response = request.execute();
response.disconnect();

spanScope.close();
parentSpan.end();

List<SpanData> spans = spanExporter.getFinishedSpanItems();
assertEquals(1, spans.size());
SpanData span = spans.get(0);
String urlFull = span.getAttributes().get(HttpTracingRequestInitializer.URL_FULL);

assertFalse(urlFull.contains("user:pass"));
Comment thread
ldetmer marked this conversation as resolved.
}

@Test
public void testAddRequestBodySizeToSpan_ExceptionHandled() throws IOException {
HttpContent content = mock(HttpContent.class);
Expand Down Expand Up @@ -367,6 +411,7 @@ private void closeAndVerifySpanData(
span.getAttributes().get(HttpTracingRequestInitializer.HTTP_RESPONSE_STATUS_CODE));
assertEquals(
method, span.getAttributes().get(HttpTracingRequestInitializer.HTTP_REQUEST_METHOD));
assertEquals(BASE_URL, span.getAttributes().get(HttpTracingRequestInitializer.URL_FULL));
if (requestBodySize >= 0) {
assertEquals(
requestBodySize,
Expand Down
Loading