Skip to content

Commit 7ebb712

Browse files
RD-12747 - secret scrubbing (#66)
1 parent 5adc9c4 commit 7ebb712

File tree

16 files changed

+546
-122
lines changed

16 files changed

+546
-122
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,3 +221,4 @@ _meta
221221
.serverless
222222
package-lock.json
223223
src/main/resources/lumigo-agent.jar
224+
.vscode/

pom.xml

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,19 @@
11
<?xml version="1.0" encoding="UTF-8"?>
2-
<project xmlns="http://maven.apache.org/POM/4.0.0"
3-
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
53
<modelVersion>4.0.0</modelVersion>
6-
74
<groupId>io.lumigo</groupId>
85
<artifactId>java-tracer</artifactId>
96
<version>1.0.42</version>
107
<packaging>jar</packaging>
11-
128
<name>Lumigo java tracer</name>
139
<description>The Lumigo java tracer for serverless functions</description>
1410
<url>https://lumigo.io/</url>
15-
1611
<scm>
1712
<url>https://github.com/lumigo-io/java-tracer</url>
1813
<connection>scm:git:https://github.com:lumigo-io/java-tracer.git</connection>
1914
<developerConnection>scm:git:https://github.com:lumigo-io/java-tracer.git</developerConnection>
2015
<tag>1.0.42</tag>
2116
</scm>
22-
2317
<developers>
2418
<developer>
2519
<name>Lumigo Dev Team</name>
@@ -28,21 +22,17 @@
2822
<organizationUrl>https://lumigo.io/</organizationUrl>
2923
</developer>
3024
</developers>
31-
3225
<organization>
3326
<name>Lumigo</name>
3427
<url>https://lumigo.io/</url>
3528
</organization>
36-
3729
<licenses>
3830
<license>
3931
<name>Apache License, Version 2.0</name>
4032
<url>http://www.apache.org/licenses/LICENSE-2.0.txt</url>
4133
<distribution>repo</distribution>
4234
</license>
4335
</licenses>
44-
45-
4636
<distributionManagement>
4737
<snapshotRepository>
4838
<id>ossrh</id>
@@ -53,8 +43,6 @@
5343
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
5444
</repository>
5545
</distributionManagement>
56-
57-
5846
<properties>
5947
<maven.compiler.source>1.8</maven.compiler.source>
6048
<maven.compiler.target>1.8</maven.compiler.target>
@@ -159,7 +147,7 @@
159147
<dependency>
160148
<groupId>org.projectlombok</groupId>
161149
<artifactId>lombok</artifactId>
162-
<version>1.18.22</version>
150+
<version>1.18.32</version>
163151
<scope>provided</scope>
164152
</dependency>
165153
<dependency>
@@ -182,7 +170,11 @@
182170
<artifactId>byte-buddy-agent</artifactId>
183171
<version>1.14.14</version>
184172
</dependency>
185-
173+
<dependency>
174+
<groupId>org.json</groupId>
175+
<artifactId>json</artifactId>
176+
<version>20210307</version>
177+
</dependency>
186178
<!-- Testing dependencies -->
187179
<dependency>
188180
<groupId>org.junit.jupiter</groupId>
@@ -233,7 +225,7 @@
233225
<includes>
234226
<include>**/lumigo-version.txt</include>
235227
</includes>
236-
</resource>
228+
</resource>
237229
</resources>
238230
<plugins>
239231
<!-- Used to make it so the JavaDoc and sources are included. -->
@@ -267,8 +259,7 @@
267259
</executions>
268260
</plugin>
269261
<!-- End of sources/javadoc inclusion. -->
270-
271-
<!-- Use for running tests-->
262+
<!-- Use for running tests -->
272263
<plugin>
273264
<groupId>org.apache.maven.plugins</groupId>
274265
<artifactId>maven-surefire-plugin</artifactId>
@@ -297,12 +288,11 @@
297288
<version>3.0.5</version>
298289
<configuration>
299290
<!--
300-
Enables analysis which takes more memory but finds more bugs.
301-
If you run out of memory, changes the value of the effort element
302-
to 'Low'.
303-
-->
291+
Enables analysis which takes more memory but finds more bugs.
292+
If you run out of memory, changes the value of the effort element
293+
to 'Low'.
294+
-->
304295
<effort>Max</effort>
305-
306296
<!-- Reports all bugs (other values are medium and max) -->
307297
<threshold>Low</threshold>
308298
<!-- Produces XML report -->
@@ -312,9 +302,7 @@
312302
<excludeFilterFile>findbugs/findbugs-exclude.xml</excludeFilterFile>
313303
</configuration>
314304
<executions>
315-
<!--
316-
Ensures that FindBugs inspects source code when project is compiled.
317-
-->
305+
<!-- Ensures that FindBugs inspects source code when project is compiled. -->
318306
<execution>
319307
<id>analyze-compile</id>
320308
<phase>compile</phase>
@@ -327,7 +315,7 @@
327315
<plugin>
328316
<groupId>org.jacoco</groupId>
329317
<artifactId>jacoco-maven-plugin</artifactId>
330-
<version>0.8.3</version>
318+
<version>0.8.11</version>
331319
<executions>
332320
<execution>
333321
<goals>
@@ -377,4 +365,4 @@
377365
</plugin>
378366
</plugins>
379367
</build>
380-
</project>
368+
</project>

scripts/checks.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,5 @@
22
set -eo pipefail
33

44
java -jar libs/google-java-format-1.7-all-deps.jar --set-exit-if-changed -i -a $(find . -type f -name "*.java" | grep ".*/src/.*java")
5-
mvn -f agent/pom.xml clean package
6-
mvn clean package
5+
mvn -Djava.security.manager=allow -f agent/pom.xml clean package
6+
mvn -Djava.security.manager=allow clean package

src/main/java/io/lumigo/core/SpansContainer.java

Lines changed: 14 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,12 @@
99
import io.lumigo.core.parsers.v1.AwsSdkV1ParserFactory;
1010
import io.lumigo.core.parsers.v2.AwsSdkV2ParserFactory;
1111
import io.lumigo.core.utils.AwsUtils;
12+
import io.lumigo.core.utils.EnvUtil;
1213
import io.lumigo.core.utils.JsonUtils;
14+
import io.lumigo.core.utils.SecretScrubber;
1315
import io.lumigo.core.utils.StringUtils;
1416
import io.lumigo.models.HttpSpan;
17+
import io.lumigo.models.Reportable;
1518
import io.lumigo.models.Span;
1619
import java.io.*;
1720
import java.util.*;
@@ -38,14 +41,14 @@ public class SpansContainer {
3841
private static final String AMZN_TRACE_ID = "_X_AMZN_TRACE_ID";
3942
private static final String FUNCTION_SPAN_TYPE = "function";
4043
private static final String HTTP_SPAN_TYPE = "http";
44+
private static final SecretScrubber secretScrubber = new SecretScrubber(new EnvUtil().getEnv());
4145

4246
private Span baseSpan;
4347
private Span startFunctionSpan;
4448
private Long rttDuration;
4549
private Span endFunctionSpan;
4650
private Reporter reporter;
4751
private List<HttpSpan> httpSpans = new LinkedList<>();
48-
4952
private static final SpansContainer ourInstance = new SpansContainer();
5053

5154
public static SpansContainer getInstance() {
@@ -68,6 +71,7 @@ private SpansContainer() {}
6871
public void init(Map<String, String> env, Reporter reporter, Context context, Object event) {
6972
this.clear();
7073
this.reporter = reporter;
74+
7175
int javaVersion = AwsUtils.parseJavaVersion(System.getProperty("java.version"));
7276
if (javaVersion > 11) {
7377
awsTracerId = System.getProperty("com.amazonaws.xray.traceHeader");
@@ -214,8 +218,8 @@ public Span getStartFunctionSpan() {
214218
return startFunctionSpan;
215219
}
216220

217-
public List<Object> getAllCollectedSpans() {
218-
List<Object> spans = new LinkedList<>();
221+
public List<Reportable> getAllCollectedSpans() {
222+
List<Reportable> spans = new LinkedList<>();
219223
spans.add(endFunctionSpan);
220224
spans.addAll(httpSpans);
221225
return spans;
@@ -518,63 +522,22 @@ protected static <T> T callIfVerbose(Callable<T> method) {
518522
}
519523
}
520524

521-
private Object prepareToSend(Object span, boolean hasError) {
522-
return reduceSpanSize(span, hasError);
525+
private Reportable prepareToSend(Reportable span, boolean hasError) {
526+
return reduceSpanSize(span.scrub(secretScrubber), hasError);
523527
}
524528

525-
private List<Object> prepareToSend(List<Object> spans, boolean hasError) {
526-
for (Object span : spans) {
527-
reduceSpanSize(span, hasError);
529+
private List<Reportable> prepareToSend(List<Reportable> spans, boolean hasError) {
530+
for (Reportable span : spans) {
531+
reduceSpanSize(span.scrub(secretScrubber), hasError);
528532
}
529533
return spans;
530534
}
531535

532-
public Object reduceSpanSize(Object span, boolean hasError) {
536+
public Reportable reduceSpanSize(Reportable span, boolean hasError) {
533537
int maxFieldSize =
534538
hasError
535539
? Configuration.getInstance().maxSpanFieldSizeWhenError()
536540
: Configuration.getInstance().maxSpanFieldSize();
537-
if (span instanceof Span) {
538-
Span functionSpan = (Span) span;
539-
functionSpan.setEnvs(
540-
StringUtils.getMaxSizeString(
541-
functionSpan.getEnvs(),
542-
Configuration.getInstance().maxSpanFieldSize()));
543-
functionSpan.setReturn_value(
544-
StringUtils.getMaxSizeString(functionSpan.getReturn_value(), maxFieldSize));
545-
functionSpan.setEvent(
546-
StringUtils.getMaxSizeString(functionSpan.getEvent(), maxFieldSize));
547-
} else if (span instanceof HttpSpan) {
548-
HttpSpan httpSpan = (HttpSpan) span;
549-
httpSpan.getInfo()
550-
.getHttpInfo()
551-
.getRequest()
552-
.setHeaders(
553-
StringUtils.getMaxSizeString(
554-
httpSpan.getInfo().getHttpInfo().getRequest().getHeaders(),
555-
maxFieldSize));
556-
httpSpan.getInfo()
557-
.getHttpInfo()
558-
.getRequest()
559-
.setBody(
560-
StringUtils.getMaxSizeString(
561-
httpSpan.getInfo().getHttpInfo().getRequest().getBody(),
562-
maxFieldSize));
563-
httpSpan.getInfo()
564-
.getHttpInfo()
565-
.getResponse()
566-
.setHeaders(
567-
StringUtils.getMaxSizeString(
568-
httpSpan.getInfo().getHttpInfo().getResponse().getHeaders(),
569-
maxFieldSize));
570-
httpSpan.getInfo()
571-
.getHttpInfo()
572-
.getResponse()
573-
.setBody(
574-
StringUtils.getMaxSizeString(
575-
httpSpan.getInfo().getHttpInfo().getResponse().getBody(),
576-
maxFieldSize));
577-
}
578-
return span;
541+
return span.reduceSize(maxFieldSize);
579542
}
580543
}

src/main/java/io/lumigo/core/configuration/Configuration.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class Configuration {
2727
public static final String LUMIGO_MAX_RESPONSE_SIZE = "LUMIGO_MAX_RESPONSE_SIZE";
2828
public static final String LUMIGO_MAX_SIZE_FOR_REQUEST = "LUMIGO_MAX_SIZE_FOR_REQUEST";
2929
public static final String LUMIGO_INSTRUMENTATION = "LUMIGO_INSTRUMENTATION";
30+
public static final String LUMIGO_SECRET_MASKING_REGEX = "LUMIGO_SECRET_MASKING_REGEX";
3031

3132
private static Configuration instance;
3233
private LumigoConfiguration inlineConf;

src/main/java/io/lumigo/core/network/Reporter.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import io.lumigo.core.configuration.Configuration;
44
import io.lumigo.core.utils.JsonUtils;
55
import io.lumigo.core.utils.StringUtils;
6+
import io.lumigo.models.Reportable;
67
import java.io.IOException;
78
import java.util.Collections;
89
import java.util.LinkedList;
@@ -21,11 +22,11 @@ public Reporter() {
2122
.build();
2223
}
2324

24-
public long reportSpans(Object span, int maxSize) throws IOException {
25+
public long reportSpans(Reportable span, int maxSize) throws IOException {
2526
return reportSpans(Collections.singletonList(span), maxSize);
2627
}
2728

28-
public long reportSpans(List<Object> spans, int maxSize) throws IOException {
29+
public long reportSpans(List<Reportable> spans, int maxSize) throws IOException {
2930
long time = System.currentTimeMillis();
3031
List<String> spansAsStringList = new LinkedList<>();
3132
int sizeCount = 0;
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package io.lumigo.core.utils;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.regex.Pattern;
7+
import org.json.JSONArray;
8+
import org.json.JSONObject;
9+
10+
public class SecretScrubber {
11+
private List<Pattern> scrubbingPatterns;
12+
13+
private static final String SECRET_PLACEHOLDER = "****";
14+
15+
public SecretScrubber(Map<String, String> env) {
16+
this.scrubbingPatterns = new SecretScrubbingPatternProvider(env).getScrubbingPatterns();
17+
}
18+
19+
public String scrubStringifiedObject(String stringifiedObject) {
20+
try {
21+
JSONObject jsonObject = new JSONObject(stringifiedObject);
22+
return scrubJsonObject(jsonObject, this.scrubbingPatterns).toString();
23+
} catch (Exception e) {
24+
return stringifiedObject;
25+
}
26+
}
27+
28+
private JSONObject scrubJsonObject(JSONObject jsonObject, List<Pattern> patterns) {
29+
for (String key : jsonObject.keySet()) {
30+
Object value = jsonObject.get(key);
31+
32+
if (value instanceof String && isSecret(key, patterns)) {
33+
jsonObject.put(key, SECRET_PLACEHOLDER);
34+
} else if (value instanceof JSONArray) {
35+
ArrayList<Object> scrubbedArray = new ArrayList<>();
36+
37+
for (Object item : (JSONArray) value) {
38+
if (item instanceof String && isSecret(key, patterns)) {
39+
scrubbedArray.add(SECRET_PLACEHOLDER);
40+
} else if (item instanceof JSONObject) {
41+
scrubbedArray.add(scrubJsonObject((JSONObject) item, patterns));
42+
} else {
43+
scrubbedArray.add(item);
44+
}
45+
}
46+
47+
jsonObject.put(key, scrubbedArray.toArray());
48+
49+
} else if (value instanceof JSONObject) {
50+
jsonObject.put(key, scrubJsonObject((JSONObject) value, patterns));
51+
}
52+
}
53+
54+
return jsonObject;
55+
}
56+
57+
private boolean isSecret(String value, List<Pattern> patterns) {
58+
for (Pattern pattern : patterns) {
59+
if (pattern.matcher(value).matches()) {
60+
return true;
61+
}
62+
}
63+
64+
return false;
65+
}
66+
}

0 commit comments

Comments
 (0)