Skip to content

Commit 0150655

Browse files
fix: enforce w3c trace context value validation (#777)
* fix: enforce w3c trace context value validation validate length and characters of the w3c trace context value. see https://www.w3.org/TR/trace-context/#traceparent-header-field-values refactor unit testing to bring invalid w3c trace context tests to separate file Fixes #774 * 🦉 Updates from OwlBot See https://github.com/googleapis/repo-automation-bots/blob/main/packages/owl-bot/README.md * chore: fix bug in formatting validation change length of the span field from 12 to 16 according to the standard * chore: refactor w3c format regex Co-authored-by: Owl Bot <gcf-owl-bot[bot]@users.noreply.github.com>
1 parent 746a011 commit 0150655

File tree

4 files changed

+78
-60
lines changed

4 files changed

+78
-60
lines changed

README.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,13 @@ implementation 'com.google.cloud:google-cloud-logging'
5858
If you are using Gradle without BOM, add this to your dependencies
5959

6060
```Groovy
61-
implementation 'com.google.cloud:google-cloud-logging:3.5.0'
61+
implementation 'com.google.cloud:google-cloud-logging:3.5.1'
6262
```
6363

6464
If you are using SBT, add this to your dependencies
6565

6666
```Scala
67-
libraryDependencies += "com.google.cloud" % "google-cloud-logging" % "3.5.0"
67+
libraryDependencies += "com.google.cloud" % "google-cloud-logging" % "3.5.1"
6868
```
6969

7070
## Authentication

google-cloud-logging/src/main/java/com/google/cloud/logging/Context.java

+14-19
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,17 @@
1818

1919
import com.google.cloud.logging.HttpRequest.RequestMethod;
2020
import com.google.common.base.MoreObjects;
21-
import com.google.common.base.Strings;
2221
import java.util.Objects;
22+
import java.util.regex.Matcher;
23+
import java.util.regex.Pattern;
2324

2425
/** Class to hold context attributes including information about {@see HttpRequest} and tracing. */
2526
public class Context {
27+
// validate W3C trace context value on load according to the existing version format.
28+
// see https://www.w3.org/TR/trace-context/#traceparent-header-field-values for details.
29+
private static final Pattern W3C_TRACE_CONTEXT_FORMAT =
30+
Pattern.compile(
31+
"^00-(?!00000000000000000000000000000000)[0-9a-f]{32}-(?!0000000000000000)[0-9a-f]{16}-[0-9a-f]{2}$");
2632
private final HttpRequest request;
2733
private final String traceId;
2834
private final String spanId;
@@ -142,26 +148,15 @@ public Builder loadCloudTraceContext(String cloudTrace) {
142148
*/
143149
public Builder loadW3CTraceParentContext(String traceParent) throws IllegalArgumentException {
144150
if (traceParent != null) {
145-
String[] fields = traceParent.split("-");
146-
if (fields.length > 3) {
147-
String versionFormat = fields[0];
148-
if (!versionFormat.equals("00")) {
149-
throw new IllegalArgumentException("Not supporting versionFormat other than \"00\"");
150-
}
151-
} else {
151+
Matcher validator = W3C_TRACE_CONTEXT_FORMAT.matcher(traceParent.toLowerCase());
152+
if (!validator.matches()) {
152153
throw new IllegalArgumentException(
153-
"Invalid format of the header value. Expected \"00-traceid-spanid-arguments\"");
154-
}
155-
String traceId = fields[1];
156-
if (!traceId.isEmpty()) {
157-
setTraceId(traceId);
158-
}
159-
if (!Strings.isNullOrEmpty(traceId)) {
160-
String spanId = fields[2];
161-
if (!spanId.isEmpty()) {
162-
setSpanId(spanId);
163-
}
154+
"Invalid format of the header value. The value does not match W3C Trace Context version \"00\"");
164155
}
156+
String[] fields = traceParent.split("-");
157+
setTraceId(fields[1]);
158+
setSpanId(fields[2]);
159+
// fields[3] contains flag(s)
165160
}
166161
return this;
167162
}

google-cloud-logging/src/test/java/com/google/cloud/logging/ContextTest.java

+5-39
Original file line numberDiff line numberDiff line change
@@ -132,50 +132,16 @@ public void testParsingCloudTraceContext() {
132132

133133
@Test
134134
public void testParsingW3CTraceParent() {
135-
final String TRACEPARENT_NO_TRACE = "00--SPAN_ID-FLAGS";
136-
final String TRACEPARENT_TRACE_ONLY = "00-" + TEST_TRACE_ID + "--SPAN_ID-FLAGS";
137-
final String TRACEPARENT_TRACE_FULL = "00-" + TEST_TRACE_ID + "-" + TEST_SPAN_ID + "-FLAGS";
135+
final String W3C_TEST_TRACE_ID = "12345678901234567890123456789012";
136+
final String W3C_TEST_SPAN_ID = "1234567890123456";
137+
final String W3C_TRACE_CONTEXT = "00-" + W3C_TEST_TRACE_ID + "-" + W3C_TEST_SPAN_ID + "-00";
138138

139139
Context.Builder builder = Context.newBuilder();
140140

141141
builder.loadW3CTraceParentContext(null);
142142
assertTraceAndSpan(builder.build(), null, null);
143-
builder.loadW3CTraceParentContext(TRACEPARENT_NO_TRACE);
144-
assertTraceAndSpan(builder.build(), null, null);
145-
builder.loadW3CTraceParentContext(TRACEPARENT_TRACE_ONLY);
146-
assertTraceAndSpan(builder.build(), TEST_TRACE_ID, null);
147-
builder.loadW3CTraceParentContext(TRACEPARENT_TRACE_FULL);
148-
assertTraceAndSpan(builder.build(), TEST_TRACE_ID, TEST_SPAN_ID);
149-
}
150-
151-
@Test(expected = IllegalArgumentException.class)
152-
public void testEmptyW3CTraceParent() {
153-
Context.Builder builder = Context.newBuilder();
154-
builder.loadW3CTraceParentContext("");
155-
}
156-
157-
@Test(expected = IllegalArgumentException.class)
158-
public void testInvalidFormatW3CTraceParent() {
159-
Context.Builder builder = Context.newBuilder();
160-
builder.loadW3CTraceParentContext("TRACE_ID/SPAN_ID;o=TRACE_TRUE");
161-
}
162-
163-
@Test(expected = IllegalArgumentException.class)
164-
public void testInvalidFormatW3CTraceParent1Dash() {
165-
Context.Builder builder = Context.newBuilder();
166-
builder.loadW3CTraceParentContext("00-TRACE_ID");
167-
}
168-
169-
@Test(expected = IllegalArgumentException.class)
170-
public void testInvalidFormatW3CTraceParentWithoutFlag() {
171-
Context.Builder builder = Context.newBuilder();
172-
builder.loadW3CTraceParentContext("00-TRACE_ID-SPAN_ID-");
173-
}
174-
175-
@Test(expected = IllegalArgumentException.class)
176-
public void testInvalidVersionW3CTraceParent() {
177-
Context.Builder builder = Context.newBuilder();
178-
builder.loadW3CTraceParentContext("01-TRACE_ID-SPAN_ID-FLAGS");
143+
builder.loadW3CTraceParentContext(W3C_TRACE_CONTEXT);
144+
assertTraceAndSpan(builder.build(), W3C_TEST_TRACE_ID, W3C_TEST_SPAN_ID);
179145
}
180146

181147
private void assertTraceAndSpan(Context context, String expectedTraceId, String expectedSpanId) {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* Copyright 2021 Google LLC
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.google.cloud.logging;
18+
19+
import java.util.Arrays;
20+
import java.util.Collection;
21+
import org.junit.Test;
22+
import org.junit.runner.RunWith;
23+
import org.junit.runners.Parameterized;
24+
import org.junit.runners.Parameterized.Parameters;
25+
26+
@RunWith(Parameterized.class)
27+
public class InvalidContextTest {
28+
@Parameters
29+
public static Collection<String> data() {
30+
final String[] INVALID_W3C_TRACE_CONTEXTS = {
31+
"",
32+
"abc/efg",
33+
"01-something",
34+
"00-123456789012345678901234567890",
35+
"00-12345678901234567890123456789012",
36+
"00-12345678901234567890123456789012345",
37+
"00-12345678901234567890123456789012-123456789012345",
38+
"00-12345678901234567890123456789012-1234567890123456",
39+
"00-12345678901234567890123456789012-12345678901234567",
40+
"00-12345678901234567890123456789012-1234567890123456-1",
41+
"00-12345678901234567890123456789012-1234567890123456-123"
42+
};
43+
return Arrays.asList(INVALID_W3C_TRACE_CONTEXTS);
44+
}
45+
46+
private final String traceContext;
47+
48+
public InvalidContextTest(String traceContext) {
49+
this.traceContext = traceContext;
50+
}
51+
52+
@Test(expected = IllegalArgumentException.class)
53+
public void testAssertionInvalidContext() {
54+
Context.Builder builder = Context.newBuilder();
55+
builder.loadW3CTraceParentContext(traceContext);
56+
}
57+
}

0 commit comments

Comments
 (0)