Privacy and network traffic
Looking for the previous SDK? See the 6.x network privacy page.
Disabling network traffic collection
Network capture can be disabled via the CaptureNetwork option — see
configuration.
Sanitizing network events
7.0 uses the generic EventFilter<T> interface. Its single
filter(event, callback) method hands you the event and a Callback1 to
invoke with the result: call callback.run(event) to keep the (possibly
mutated) NetworkEvent, or callback.run(null) to drop it. The event type is
NetworkEvent (package com.bugsee.library.contracts.exchange), which exposes
getters/setters for the event fields (the no-body reason is exposed via
getBodyAbsenceReason()).
- Java
- Kotlin
Bugsee.setNetworkEventFilter((event, callback) -> {
// URL
String url = event.getUrl();
if (url != null && url.contains("token")) {
event.setUrl(url.replaceAll("token=\\S+", "token=[REDACTED]"));
}
// Headers
Map<String, String> headers = event.getHeaders();
if (headers != null) {
headers.remove("Authorization");
event.setHeaders(headers);
}
// Body
String body = event.getBody();
if (body != null && body.contains("\"password\"")) {
event.setBody("[REDACTED]");
}
// Error text (captured for failed requests)
if (event.getErrorDescription() != null) {
event.setErrorDescription("…");
}
callback.run(event); // keep
// callback.run(null); // drop
});
Bugsee.setNetworkEventFilter { event, callback ->
event.url?.takeIf { it.contains("token") }?.let {
event.url = it.replace(Regex("token=\\S+"), "token=[REDACTED]")
}
event.headers?.let { headers ->
headers.remove("Authorization")
event.headers = headers
}
event.body?.takeIf { it.contains("\"password\"") }?.let {
event.body = "[REDACTED]"
}
event.errorDescription?.let { event.errorDescription = "…" }
callback.run(event) // keep — or `callback.run(null)` to drop
}
A filter replaces the built-in redaction
Without a filter, Bugsee runs its default sanitizer on every network event
(the CaptureNetworkUseDefaultSanitizer option, on by default). It replaces
these values with <redacted> (%3Credacted%3E inside URLs). Key matching is
case-insensitive.
- Headers:
Authorization,Proxy-Authorization,Cookie,Set-Cookie,X-Api-Key,X-Auth-Token,X-CSRF-Token,X-Forwarded-For,X-Real-IP. - URL query parameters and JSON, form-encoded or
key: valueline bodies: keys such aspass,pin,ssn,cvv,card_number,private_key,sidand presigned-URL signatures. - Any header, query or body key whose name contains
password,passwd,passcode,secret,token,sessionorapikey/api_key/api-key. - Sensitive query values quoted in error messages.
It also removes user:password@ credentials from URLs and error messages.
Once a network filter is installed, either with Bugsee.setNetworkEventFilter
or in the manifest, the default
sanitizer no longer runs and your filter is the only redaction. A filter that
only adds or renames a field records Authorization headers, cookies and
password fields as they are. Removing the filter with
Bugsee.setNetworkEventFilter(null) turns the default sanitizer back on,
unless you disabled CaptureNetworkUseDefaultSanitizer.
To keep the built-in redaction and add your own, call the SDK's default
sanitizer, Bugsee.getDefaultNetworkSanitizer(), at the start of your filter:
- Java
- Kotlin
Bugsee.setNetworkEventFilter((event, callback) -> {
Bugsee.getDefaultNetworkSanitizer().sanitize(event); // built-in redaction
// ...your own redaction...
callback.run(event);
});
Bugsee.setNetworkEventFilter { event, callback ->
Bugsee.getDefaultNetworkSanitizer().sanitize(event) // built-in redaction
// ...your own redaction...
callback.run(event)
}
getDefaultNetworkSanitizer() works before Bugsee.launch(), so you can use
it in a manifest-declared filter, and
you can call it for every event. Besides sanitize(event), which redacts the
URL, headers, body and error messages, it has sanitizeUrl(event) and
sanitizeErrorMessage(event), which redact only the URL or only the error
messages.
Bugsee.getDefaultNetworkSanitizer() is new in SDK 7.3.0. On SDK 7.0.3
through 7.2.0, call the static NetworkDataSanitizer.sanitize(event) (package
com.bugsee.library.shared.security.privacy) instead; that class is deprecated
from 7.3.0 but still works. Earlier versions have no public sanitizer.
If your code wildcard-imports both com.bugsee.library.contracts.exchange.* and
com.bugsee.library.shared.security.privacy.*, the compiler reports
NetworkDataSanitizer as ambiguous after the upgrade. Import the one you mean by
its full name, or use Bugsee.getDefaultNetworkSanitizer(), which needs no
import.
Capture from OkHttp 3/4, Ktor 2/3, and Cronet is wired automatically by the Bugsee Gradle plugin through the matching extension modules — no manual interceptor registration is required.
Declaring the filter in the manifest
You can also point Bugsee at a network filter from AndroidManifest.xml, with
no code. Add a com.bugsee.filter.network-event <meta-data> whose value is a
class that implements EventFilter<NetworkEvent> and has a public no-arg
constructor. Bugsee installs it itself as part of launch, so it does not depend on
when your code runs. With auto-initialization, capture can start before your
Application.onCreate(), and a filter set there in code misses what was
captured before the call (those events get the built-in redaction instead,
when it is enabled).
<application>
<meta-data android:name="com.bugsee.filter.network-event"
android:value="com.example.MyNetworkFilter" />
</application>
- Java
- Kotlin
import androidx.annotation.Keep;
import com.bugsee.library.contracts.common.Callback1;
import com.bugsee.library.contracts.exchange.EventFilter;
import com.bugsee.library.contracts.exchange.NetworkEvent;
@Keep // referenced only by name in the manifest — keep it from R8
public class MyNetworkFilter implements EventFilter<NetworkEvent> {
public MyNetworkFilter() { } // required public no-arg constructor
@Override
public void filter(NetworkEvent event, Callback1<NetworkEvent> callback) {
String url = event.getUrl();
if (url != null && url.contains("token")) {
event.setUrl(url.replaceAll("token=\\S+", "token=[REDACTED]"));
}
callback.run(event); // pass null to drop
}
}
import androidx.annotation.Keep
import com.bugsee.library.contracts.common.Callback1
import com.bugsee.library.contracts.exchange.EventFilter
import com.bugsee.library.contracts.exchange.NetworkEvent
@Keep // referenced only by name in the manifest — keep it from R8
class MyNetworkFilter : EventFilter<NetworkEvent> {
override fun filter(event: NetworkEvent, callback: Callback1<NetworkEvent>) {
event.url?.takeIf { it.contains("token") }?.let {
event.url = it.replace(Regex("token=\\S+"), "token=[REDACTED]")
}
callback.run(event) // pass null to drop
}
}
A filter set in code with Bugsee.setNetworkEventFilter(...) takes precedence
over the manifest one; use one or the other, not both. A manifest filter also
replaces the built-in redaction.
Because the class is referenced only by name, keep it
from R8 — annotate it @Keep or add -keep class com.example.MyNetworkFilter { <init>(); }.
The same mechanism is available for logs and breadcrumbs.