Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
2ba9494
feat(scrubbing): add StringUrlSanitizer and DefaultUrlSanitizer
buongarzoni Jul 13, 2026
9049736
feat(scrubbing): add ScrubDataTransformer
buongarzoni Jul 13, 2026
7a9ca73
feat(config): expose redactedKeys and urlSanitizer
buongarzoni Jul 13, 2026
00dc4cb
feat(notifier): apply built-in scrubbing to every payload
buongarzoni Jul 13, 2026
bf3629d
refactor(okhttp): reuse the shared DefaultUrlSanitizer
buongarzoni Jul 13, 2026
9fee327
refactor(api): update imports
buongarzoni Jul 13, 2026
347ad48
refactor(scrubbing): update imports
buongarzoni Jul 13, 2026
306b105
refactor(config): update imports
buongarzoni Jul 13, 2026
52d5d40
refactor(okhttp): reuse the shared DefaultUrlSanitizer
buongarzoni Jul 13, 2026
82fb70b
fix(scrubbing): scrub Frame.locals in Body.rollbarThreads
buongarzoni Jul 13, 2026
8c06fd1
fix(scrubbing): match percent-encoded query parameter names
buongarzoni Jul 13, 2026
a09f485
fix(scrubbing): scrub Request.params and Request.metadata
buongarzoni Jul 13, 2026
57399ec
fix(scrubbing): traverse collections and arrays when scrubbing nested…
buongarzoni Aug 3, 2026
5482e72
fix(telemetry): sanitize URLs recorded as network telemetry events
buongarzoni Aug 3, 2026
f7bc6f3
test(scrubbing): cover ordering, reconfiguration and the okhttp sanit…
buongarzoni Aug 3, 2026
4c21b07
docs: add scrubbing documentation
buongarzoni Aug 10, 2026
1fc3ed6
feat(scrubbing): seed field scrubbing with a built-in key list
buongarzoni Aug 11, 2026
f016ac2
feat(config): expose useDefaultRedactedKeys
buongarzoni Aug 11, 2026
9ee5bc7
test(scrubbing): cover the built-in key list and the opt-out
buongarzoni Aug 11, 2026
f357b6c
test(scrubbing): prove secrets are redacted with no configuration
buongarzoni Aug 11, 2026
2ede510
docs: document the built-in redacted key list
buongarzoni Aug 11, 2026
0aa3993
perf(scrubbing): match literal keys without the regex engine
buongarzoni Aug 14, 2026
0c5a376
fix(scrubbing): redact Message.metadata in the body content + ignore …
buongarzoni Sep 14, 2026
01cd471
fix(scrubbing): redact Message.metadata in the body content + ignore …
buongarzoni Sep 14, 2026
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
Prev Previous commit
Next Next commit
feat(config): expose useDefaultRedactedKeys
  • Loading branch information
buongarzoni committed Aug 11, 2026
commit f016ac299705e090235d9beacdfa44f93cead89c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ protected RollbarBase(C config, BodyFactory bodyFactory, RESULT emptyResult) {
this.bodyFactory = bodyFactory;
this.emptyResult = emptyResult;
this.telemetryEventTracker = config.telemetryEventTracker();
this.builtInScrubber = new ScrubDataTransformer(config.redactedKeys(), config.urlSanitizer());
this.builtInScrubber = new ScrubDataTransformer(
config.redactedKeys(), config.urlSanitizer(), config.useDefaultRedactedKeys());
this.telemetryUrlSanitizer = urlSanitizerOf(config);
}

Expand Down Expand Up @@ -144,7 +145,8 @@ protected void configure(C config) {
this.config = config;
configureTruncation(config);
processAppPackages(config);
this.builtInScrubber = new ScrubDataTransformer(config.redactedKeys(), config.urlSanitizer());
this.builtInScrubber = new ScrubDataTransformer(
config.redactedKeys(), config.urlSanitizer(), config.useDefaultRedactedKeys());
this.telemetryUrlSanitizer = urlSanitizerOf(config);
} finally {
this.configWriteLock.unlock();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -229,15 +229,29 @@ default boolean compressPayload() {
/**
* Keys (matched as case-insensitive regex) whose values should be redacted in headers,
* query/POST parameters, custom data, and {@code Frame.locals} before sending to Rollbar.
* The default header deny-list (Authorization, Cookie, etc.) is always applied regardless
* of this list.
* These are additive to
* {@link com.rollbar.notifier.scrubbing.ScrubDataTransformer#DEFAULT_REDACTED_KEYS} (unless
* {@link #useDefaultRedactedKeys()} is false) and to the default header deny-list
* (Authorization, Cookie, etc.), which is always applied regardless of this list.
*
* @return list of regex patterns; empty list by default.
*/
default List<String> redactedKeys() {
return Collections.emptyList();
}

/**
* Whether {@link com.rollbar.notifier.scrubbing.ScrubDataTransformer#DEFAULT_REDACTED_KEYS}
* (password, secret, token, etc.) are redacted in addition to {@link #redactedKeys()}. Set to
* false to match only the keys you configure; the header deny-list and the URL sanitizer still
* apply.
*
* @return true to apply the built-in key list; true by default.
*/
default boolean useDefaultRedactedKeys() {
return true;
}

/**
* URL sanitizer applied to {@link com.rollbar.api.payload.data.Request#getUrl()} before the
* payload is sent. Defaults to {@link DefaultUrlSanitizer#INSTANCE} which strips userinfo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.rollbar.notifier.provider.Provider;
import com.rollbar.notifier.provider.notifier.NotifierProvider;
import com.rollbar.notifier.provider.timestamp.TimestampProvider;
import com.rollbar.notifier.scrubbing.ScrubDataTransformer;
import com.rollbar.notifier.sender.BufferedSender;
import com.rollbar.notifier.sender.Sender;
import com.rollbar.notifier.sender.SyncSender;
Expand Down Expand Up @@ -93,6 +94,8 @@ public class ConfigBuilder {

protected List<String> redactedKeys;

protected boolean useDefaultRedactedKeys = true;

protected StringUrlSanitizer urlSanitizer;

private int maximumTelemetryData =
Expand Down Expand Up @@ -149,6 +152,7 @@ private ConfigBuilder(Config config) {
this.maximumTelemetryData = config.maximumTelemetryData();
this.telemetryEventTracker = config.telemetryEventTracker();
this.redactedKeys = config.redactedKeys();
this.useDefaultRedactedKeys = config.useDefaultRedactedKeys();
this.urlSanitizer = config.urlSanitizer();
}

Expand Down Expand Up @@ -533,8 +537,9 @@ public ConfigBuilder telemetryEventTracker(TelemetryEventTracker telemetryEventT

/**
* Keys (matched as case-insensitive regex) whose values will be redacted in request headers,
* query/POST parameters, custom data, and {@code Frame.locals}. These are additive to the
* built-in header deny-list (Authorization, Cookie, etc.).
* query/POST parameters, custom data, and {@code Frame.locals}. These are additive to
* {@link ScrubDataTransformer#DEFAULT_REDACTED_KEYS} and to the built-in header deny-list
* (Authorization, Cookie, etc.).
*
* @param redactedKeys list of regex patterns.
* @return the builder instance.
Expand All @@ -544,6 +549,20 @@ public ConfigBuilder redactedKeys(List<String> redactedKeys) {
return this;
}

/**
* Whether {@link ScrubDataTransformer#DEFAULT_REDACTED_KEYS} (password, secret, token, etc.)
* are redacted in addition to {@link #redactedKeys(List)}. Defaults to true; set to false to
* match only the keys you configure. The header deny-list and the URL sanitizer apply either
* way.
*
* @param useDefaultRedactedKeys true to apply the built-in key list.
* @return the builder instance.
*/
public ConfigBuilder useDefaultRedactedKeys(boolean useDefaultRedactedKeys) {
this.useDefaultRedactedKeys = useDefaultRedactedKeys;
return this;
}

/**
* URL sanitizer applied to the request URL before the payload is sent.
* Defaults to {@link DefaultUrlSanitizer#INSTANCE}.
Expand Down Expand Up @@ -659,6 +678,8 @@ private static class ConfigImpl implements Config {

private final List<String> redactedKeys;

private final boolean useDefaultRedactedKeys;

private final StringUrlSanitizer urlSanitizer;

ConfigImpl(ConfigBuilder builder) {
Expand Down Expand Up @@ -697,7 +718,8 @@ private static class ConfigImpl implements Config {
this.maximumTelemetryData = builder.maximumTelemetryData;
this.telemetryEventTracker = builder.telemetryEventTracker;
this.redactedKeys = builder.redactedKeys != null

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[P1] Seed field scrubbing with a meaningful default list

When redactedKeys is unset, this stores an empty list, so ScrubDataTransformer leaves GET/POST parameters, request.query_string, custom data, metadata, and Frame.locals untouched. Stripping the query from request.url does not close that gap: the web request provider serializes parsed GET parameters and the raw query string separately, so /login?password=hunter2 still sends hunter2 under both request.get.password and request.query_string with the default configuration.

That means the default behavior only protects the built-in header deny-list and URL strings; it does not satisfy the stated goal that sensitive data is redacted by default. Please seed this with an additive built-in field list (for example password/passwd, secret, token/access_token, auth/authentication/authorization), ideally with an explicit override mechanism, and add a no-configuration end-to-end test proving the secret is absent from every relevant request representation.

? builder.redactedKeys : Collections.<String>emptyList();
? builder.redactedKeys : Collections.emptyList();
this.useDefaultRedactedKeys = builder.useDefaultRedactedKeys;
this.urlSanitizer = builder.urlSanitizer != null
? builder.urlSanitizer : DefaultUrlSanitizer.INSTANCE;
}
Expand Down Expand Up @@ -867,6 +889,11 @@ public List<String> redactedKeys() {
return redactedKeys;
}

@Override
public boolean useDefaultRedactedKeys() {
return useDefaultRedactedKeys;
}

@Override
public StringUrlSanitizer urlSanitizer() {
return urlSanitizer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import com.rollbar.notifier.provider.Provider;
import com.rollbar.notifier.provider.notifier.NotifierProvider;
import com.rollbar.notifier.provider.timestamp.TimestampProvider;
import com.rollbar.notifier.scrubbing.ScrubDataTransformer;
import com.rollbar.notifier.sender.SyncSender;
import com.rollbar.notifier.sender.json.JsonSerializer;
import com.rollbar.notifier.telemetry.RollbarTelemetryEventTracker;
Expand Down Expand Up @@ -65,6 +66,7 @@ public final class ConfigBuilder {
private boolean truncateLargePayloads;
private boolean compressPayload;
private List<String> redactedKeys;
private boolean useDefaultRedactedKeys = true;
private StringUrlSanitizer urlSanitizer;
private int maximumTelemetryData =
RollbarTelemetryEventTracker.MAXIMUM_CAPACITY_FOR_TELEMETRY_EVENTS;
Expand Down Expand Up @@ -116,6 +118,7 @@ private ConfigBuilder(Config config) {
this.maximumTelemetryData = config.maximumTelemetryData();
this.telemetryEventTracker = config.telemetryEventTracker();
this.redactedKeys = config.redactedKeys();
this.useDefaultRedactedKeys = config.useDefaultRedactedKeys();
this.urlSanitizer = config.urlSanitizer();
}

Expand Down Expand Up @@ -519,8 +522,9 @@ public ConfigBuilder telemetryEventTracker(TelemetryEventTracker telemetryEventT

/**
* Keys (matched as case-insensitive regex) whose values will be redacted in request headers,
* query/POST parameters, custom data, and {@code Frame.locals}. These are additive to the
* built-in header deny-list (Authorization, Cookie, etc.).
* query/POST parameters, custom data, and {@code Frame.locals}. These are additive to
* {@link ScrubDataTransformer#DEFAULT_REDACTED_KEYS} and to the built-in header deny-list
* (Authorization, Cookie, etc.).
*
* @param redactedKeys list of regex patterns.
* @return the builder instance.
Expand All @@ -530,6 +534,20 @@ public ConfigBuilder redactedKeys(List<String> redactedKeys) {
return this;
}

/**
* Whether {@link ScrubDataTransformer#DEFAULT_REDACTED_KEYS} (password, secret, token, etc.)
* are redacted in addition to {@link #redactedKeys(List)}. Defaults to true; set to false to
* match only the keys you configure. The header deny-list and the URL sanitizer apply either
* way.
*
* @param useDefaultRedactedKeys true to apply the built-in key list.
* @return the builder instance.
*/
public ConfigBuilder useDefaultRedactedKeys(boolean useDefaultRedactedKeys) {
this.useDefaultRedactedKeys = useDefaultRedactedKeys;
return this;
}

/**
* URL sanitizer applied to the request URL before the payload is sent.
* Defaults to {@link DefaultUrlSanitizer#INSTANCE}.
Expand Down Expand Up @@ -616,6 +634,7 @@ private static class ConfigImpl implements Config {
private final int maximumTelemetryData;
private final TelemetryEventTracker telemetryEventTracker;
private final List<String> redactedKeys;
private final boolean useDefaultRedactedKeys;
private final StringUrlSanitizer urlSanitizer;

ConfigImpl(ConfigBuilder builder) {
Expand Down Expand Up @@ -654,6 +673,7 @@ private static class ConfigImpl implements Config {
this.telemetryEventTracker = builder.telemetryEventTracker;
this.redactedKeys = builder.redactedKeys != null
? builder.redactedKeys : Collections.emptyList();
this.useDefaultRedactedKeys = builder.useDefaultRedactedKeys;
this.urlSanitizer = builder.urlSanitizer != null
? builder.urlSanitizer : DefaultUrlSanitizer.INSTANCE;
}
Expand Down Expand Up @@ -818,6 +838,11 @@ public List<String> redactedKeys() {
return redactedKeys;
}

@Override
public boolean useDefaultRedactedKeys() {
return useDefaultRedactedKeys;
}

@Override
public StringUrlSanitizer urlSanitizer() {
return urlSanitizer;
Expand Down