Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Redacted Keys #217

Open
wants to merge 24 commits into
base: next
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## TBD

### Changed

- Renamed the configuration option `filters` to `redactedKeys`. `filters` is now marked as deprecated and will be removed in the next major release. [#217](https://github.com/bugsnag/bugsnag-java/pull/217)

### Bug Fixes

* Update `BugsnagImportSelector` to allow major versions that do not have a minor version.
fixes [issue #211](https://github.com/bugsnag/bugsnag-java/issues/211).
[#213](https://github.com/bugsnag/bugsnag-java/pull/213)
Expand Down
36 changes: 35 additions & 1 deletion bugsnag/src/main/java/com/bugsnag/Bugsnag.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.bugsnag.callbacks.Callback;
import com.bugsnag.delivery.Delivery;
import com.bugsnag.delivery.HttpDelivery;
import com.bugsnag.util.ConcatList;
import com.bugsnag.util.DaemonThreadFactory;

import org.slf4j.Logger;
Expand All @@ -11,8 +12,11 @@
import java.io.Closeable;
import java.lang.Thread.UncaughtExceptionHandler;
import java.net.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
Expand All @@ -22,6 +26,7 @@
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

public class Bugsnag implements Closeable {
private static final Logger LOGGER = LoggerFactory.getLogger(Bugsnag.class);
Expand Down Expand Up @@ -232,12 +237,41 @@ public void setEndpoint(String endpoint) {
* Use this when you want to ensure sensitive information, such as passwords
* or credit card information is stripped from metaData you send to Bugsnag.
* Any keys in metaData which contain these strings will be marked as
* [FILTERED] when send to Bugsnag.
* [REDACTED] when send to Bugsnag.
* @deprecated to be removed and replaced with setRedactedKeys
*
* @param filters a list of String keys to filter from metaData
*/
@Deprecated
public void setFilters(String... filters) {
config.filters = filters;

List<Pattern> patterns = new ArrayList<>();
for (String fil : filters) {
patterns.add(Pattern.compile(".*" + Pattern.quote(fil) + ".*", Pattern.CASE_INSENSITIVE));
}
setRedactedKeys(patterns.toArray(new Pattern[0]));
}

/**
* Sets which values should be removed from any metadata before sending them
* to Bugsnag.
*
* Use this if you want to ensure you don't transmit sensitive data such as
* passwords and credit card numbers. Any property whose key matches a
* redacted key will be filtered and replaced with [REDACTED].
*
* @param redactedKeys a list of Patterns to match the key of properties to be redacted from metadata
*/
public void setRedactedKeys(Pattern... redactedKeys) {
if (config.redactedKeys == null) {
config.redactedKeys = redactedKeys;
} else {
List<Pattern> currentList = Arrays.asList(config.redactedKeys);
List<Pattern> newList = Arrays.asList(redactedKeys);
ConcatList<Pattern> combinedList = new ConcatList<>(currentList, newList);
config.redactedKeys = combinedList.toArray(new Pattern[0]);
}
}

/**
Expand Down
64 changes: 55 additions & 9 deletions bugsnag/src/main/java/com/bugsnag/BugsnagAppender.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.net.Proxy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
Expand Down Expand Up @@ -48,8 +49,8 @@ public class BugsnagAppender extends UnsynchronizedAppenderBase<ILoggingEvent> {
/** Bugsnag error server endpoint. */
private String endpoint;

/** Property names that should be filtered out before sending to Bugsnag servers. */
private Set<String> filteredProperties = new HashSet<String>();
/** Property names that should be redacted before sending to Bugsnag servers. */
private Set<Pattern> redactedKeys = new HashSet<Pattern>();

/** Exception classes to be ignored. */
private Set<String> ignoredClasses = new HashSet<String>();
Expand Down Expand Up @@ -254,8 +255,8 @@ private Bugsnag createBugsnag() {
bugsnag.setTimeout(timeout);
}

if (filteredProperties.size() > 0) {
bugsnag.setFilters(filteredProperties.toArray(new String[0]));
if (redactedKeys.size() > 0) {
bugsnag.setRedactedKeys(redactedKeys.toArray(new Pattern[0]));
}

bugsnag.setIgnoreClasses(ignoredClasses.toArray(new String[0]));
Expand Down Expand Up @@ -375,23 +376,54 @@ public void setEndpoint(String endpoint) {

/**
* @see Bugsnag#setFilters(String...)
* @deprecated use #setRedactedKey(String) instead
*/
@Deprecated
public void setFilteredProperty(String filter) {
this.filteredProperties.add(filter);
this.redactedKeys.add(Pattern.compile(filter));

if (bugsnag != null) {
bugsnag.setFilters(this.filteredProperties.toArray(new String[0]));
bugsnag.setRedactedKeys(this.redactedKeys.toArray(new Pattern[0]));
}
}

/**
* @see Bugsnag#setFilters(String...)
* @deprecated use #setRedactedKeys(String) instead
*/
public void setFilteredProperties(String filters) {
this.filteredProperties.addAll(split(filters));
@Deprecated
public void setFilteredProperties(Collection<String> filters) {
this.redactedKeys.addAll(convertStringsToPatterns(filters));

if (bugsnag != null) {
bugsnag.setFilters(this.filteredProperties.toArray(new String[0]));
bugsnag.setRedactedKeys(this.redactedKeys.toArray(new Pattern[0]));
}
}

/**
* @see Bugsnag#setRedactedKeys(Pattern...)
*/
public void setRedactedKey(String redactedKey) {
Pattern pattern = Pattern.compile(redactedKey);
this.redactedKeys.add(pattern);

if (bugsnag != null) {
bugsnag.setRedactedKeys(this.redactedKeys.toArray(new Pattern[0]));
}

}

/**
* @see Bugsnag#setRedactedKeys(Pattern...)
*/
public void setRedactedKeys(Collection<String> redactedKeys) {
for (String key : redactedKeys) {
Pattern pattern = Pattern.compile(key);
this.redactedKeys.add(pattern);
}

if (bugsnag != null) {
bugsnag.setRedactedKeys(this.redactedKeys.toArray(new Pattern[0]));
}
}

Expand Down Expand Up @@ -559,6 +591,20 @@ public Bugsnag getClient() {
return bugsnag;
}

/**
* Converts a collection of strings to a collection of patterns.
*
* @param strings the collection of strings to convert
* @return a collection of patterns
*/
private Collection<Pattern> convertStringsToPatterns(Collection<String> strings) {
Collection<Pattern> patterns = new HashSet<>();
for (String str : strings) {
patterns.add(Pattern.compile(str));
}
return patterns;
}

/**
* Whether or not a logger is excluded from generating Bugsnag reports
* @param loggerName The name of the logger
Expand Down
7 changes: 7 additions & 0 deletions bugsnag/src/main/java/com/bugsnag/Configuration.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
import java.util.Map;
import java.util.concurrent.ConcurrentLinkedQueue;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.regex.Pattern;

@SuppressWarnings("visibilitymodifier")
public class Configuration {
Expand All @@ -38,6 +39,12 @@ public class Configuration {
public Delivery delivery = new AsyncHttpDelivery(SyncHttpDelivery.DEFAULT_NOTIFY_ENDPOINT);
public Delivery sessionDelivery =
new AsyncHttpDelivery(SyncHttpDelivery.DEFAULT_SESSION_ENDPOINT);
public Pattern[] redactedKeys = new Pattern[] {
Pattern.compile("password", Pattern.CASE_INSENSITIVE),
Pattern.compile("secret", Pattern.CASE_INSENSITIVE),
Pattern.compile("authorization", Pattern.CASE_INSENSITIVE),
Pattern.compile("cookie", Pattern.CASE_INSENSITIVE)
};
public String[] filters = new String[]{"password", "secret", "Authorization", "Cookie"};
public String[] ignoreClasses;
public String[] notifyReleaseStages = null;
Expand Down
4 changes: 2 additions & 2 deletions bugsnag/src/main/java/com/bugsnag/Report.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import com.bugsnag.serialization.Expose;

import com.bugsnag.util.FilteredMap;
import com.bugsnag.util.RedactedKeysMap;

import java.util.ArrayList;
import java.util.Arrays;
Expand Down Expand Up @@ -126,7 +126,7 @@ public Map<String, String> getUser() {

@Expose
public Map<String, Object> getMetaData() {
return new FilteredMap(diagnostics.metaData, Arrays.asList(config.filters));
return new RedactedKeysMap(diagnostics.metaData, Arrays.asList(config.redactedKeys));
}

@Expose
Expand Down
38 changes: 38 additions & 0 deletions bugsnag/src/main/java/com/bugsnag/util/ConcatList.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.bugsnag.util;

import java.util.AbstractList;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

public class ConcatList<E> extends AbstractList<E> {
private final List<E> combined;

/**
* Constructs a concatenation of two lists, removing duplicates.
*
* @param first the first list of elements to concatenate.
* @param second the second list of elements to concatenate.
* @throws NullPointerException if either list is null.
*/
public ConcatList(List<E> first, List<E> second) {
if (first == null || second == null) {
throw new NullPointerException("lists must not be null");
}
Set<E> uniqueElements = new LinkedHashSet<>();
uniqueElements.addAll(first);
uniqueElements.addAll(second);
this.combined = new ArrayList<>(uniqueElements);
}

@Override
public int size() {
return combined.size();
}

@Override
public E get(int index) {
return combined.get(index);
}
}
122 changes: 0 additions & 122 deletions bugsnag/src/main/java/com/bugsnag/util/FilteredMap.java

This file was deleted.

Loading