-
Notifications
You must be signed in to change notification settings - Fork 187
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: remove sensitive data when
BoxAPIException
logs request (#1284)
* fix: remove sensitive data when BoxAPIException logs request * remove wiremock setup * checkstyle * checkstyle test * allow customizing sanitization keys
- Loading branch information
Showing
3 changed files
with
149 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
package com.box.sdk; | ||
|
||
import java.util.Arrays; | ||
import java.util.HashSet; | ||
import java.util.Set; | ||
import okhttp3.Headers; | ||
import org.jetbrains.annotations.NotNull; | ||
|
||
/** | ||
* Class used to sanitize sensitive data from payload. | ||
*/ | ||
public final class BoxSensitiveDataSanitizer { | ||
private static final Set<String> SENSITIVE_KEYS = new HashSet<>(Arrays.asList("authorization", "access_token", | ||
"refresh_token", "subject_token", "token", "client_id", "client_secret", "code", "shared_link", "download_url", | ||
"jwt_private_key", "jwt_private_key_passphrase", "password")); | ||
|
||
private BoxSensitiveDataSanitizer() { | ||
} | ||
|
||
/** | ||
* Add key that should be sanitized | ||
* | ||
* @param key key to be sanitized | ||
*/ | ||
public static void addKeyToSanitize(String key) { | ||
SENSITIVE_KEYS.add(key); | ||
} | ||
|
||
@NotNull | ||
static Headers sanitizeHeaders(Headers originalHeaders) { | ||
Headers.Builder sanitizedHeadersBuilder = originalHeaders.newBuilder(); | ||
|
||
for (String originalHeaderName : originalHeaders.names()) { | ||
if (isSensitiveKey(originalHeaderName)) { | ||
sanitizedHeadersBuilder.set(originalHeaderName, "[REDACTED]"); | ||
} else { | ||
String headerValue = originalHeaders.get(originalHeaderName); | ||
if (headerValue != null) { | ||
sanitizedHeadersBuilder.set(originalHeaderName, headerValue); | ||
} | ||
} | ||
} | ||
|
||
return sanitizedHeadersBuilder.build(); | ||
} | ||
|
||
private static boolean isSensitiveKey(@NotNull String key) { | ||
return SENSITIVE_KEYS.contains(key.toLowerCase()); | ||
} | ||
} |
88 changes: 88 additions & 0 deletions
88
src/test/java/com/box/sdk/BoxSensitiveDataSanitizerTest.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
package com.box.sdk; | ||
|
||
import static org.hamcrest.MatcherAssert.assertThat; | ||
import static org.hamcrest.Matchers.is; | ||
|
||
import java.util.HashMap; | ||
import java.util.Map; | ||
import okhttp3.Headers; | ||
import org.junit.Test; | ||
|
||
public class BoxSensitiveDataSanitizerTest { | ||
@Test | ||
public void removeSensitiveDataFromHeaders() { | ||
Map<String, String> headersMap = new HashMap<>(); | ||
headersMap.put("authorization", "token"); | ||
headersMap.put("user-agent", "java-sdk"); | ||
|
||
Headers headers = Headers.of(headersMap); | ||
Headers sanitizedHeaders = BoxSensitiveDataSanitizer.sanitizeHeaders(headers); | ||
|
||
assertThat(sanitizedHeaders.size(), is(2)); | ||
assertThat(sanitizedHeaders.get("authorization"), is("[REDACTED]")); | ||
assertThat(sanitizedHeaders.get("user-agent"), is("java-sdk")); | ||
} | ||
|
||
@Test | ||
public void removeAllHeadersWhenOnlySensitiveData() { | ||
Map<String, String> headersMap = new HashMap<>(); | ||
headersMap.put("authorization", "token"); | ||
headersMap.put("password", "123"); | ||
|
||
Headers headers = Headers.of(headersMap); | ||
Headers sanitizedHeaders = BoxSensitiveDataSanitizer.sanitizeHeaders(headers); | ||
|
||
assertThat(sanitizedHeaders.size(), is(2)); | ||
assertThat(sanitizedHeaders.get("authorization"), is("[REDACTED]")); | ||
assertThat(sanitizedHeaders.get("password"), is("[REDACTED]")); | ||
} | ||
|
||
@Test | ||
public void removeSensitiveDataFromHeadersWhenUppercase() { | ||
Map<String, String> headersMap = new HashMap<>(); | ||
headersMap.put("Authorization", "token"); | ||
headersMap.put("user-agent", "java-sdk"); | ||
|
||
Headers headers = Headers.of(headersMap); | ||
Headers sanitizedHeaders = BoxSensitiveDataSanitizer.sanitizeHeaders(headers); | ||
|
||
assertThat(sanitizedHeaders.size(), is(2)); | ||
assertThat(sanitizedHeaders.get("Authorization"), is("[REDACTED]")); | ||
assertThat(sanitizedHeaders.get("user-agent"), is("java-sdk")); | ||
} | ||
|
||
@Test | ||
public void headersNotRemovedWhenNoSensitiveData() { | ||
Map<String, String> headersMap = new HashMap<>(); | ||
headersMap.put("accept", "application/json"); | ||
headersMap.put("user-agent", "java-sdk"); | ||
|
||
Headers headers = Headers.of(headersMap); | ||
Headers sanitizedHeaders = BoxSensitiveDataSanitizer.sanitizeHeaders(headers); | ||
|
||
assertThat(sanitizedHeaders.size(), is(2)); | ||
assertThat(sanitizedHeaders.get("accept"), is("application/json")); | ||
assertThat(sanitizedHeaders.get("user-agent"), is("java-sdk")); | ||
} | ||
|
||
@Test | ||
public void returnEmptyHeadersWhenEmptyHeadersPassed() { | ||
Headers headers = Headers.of(new HashMap<>()); | ||
Headers sanitizedHeaders = BoxSensitiveDataSanitizer.sanitizeHeaders(headers); | ||
|
||
assertThat(sanitizedHeaders.size(), is(0)); | ||
} | ||
|
||
@Test | ||
public void sanitizeAddedKeys() { | ||
Map<String, String> headersMap = new HashMap<>(); | ||
headersMap.put("x-auth", "token"); | ||
|
||
Headers headers = Headers.of(headersMap); | ||
BoxSensitiveDataSanitizer.addKeyToSanitize("x-auth"); | ||
Headers sanitizedHeaders = BoxSensitiveDataSanitizer.sanitizeHeaders(headers); | ||
|
||
assertThat(sanitizedHeaders.size(), is(1)); | ||
assertThat(sanitizedHeaders.get("x-auth"), is("[REDACTED]")); | ||
} | ||
} |