From 585aebecc437584880a76984f2199d25c4ebc2a6 Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Thu, 24 Sep 2026 09:36:36 +0500 Subject: [PATCH 1/2] docs(android): a network filter replaces the built-in redaction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Installing a network filter, in code or in the manifest, turns off the default sanitizer (CaptureNetworkUseDefaultSanitizer). From then on the host filter is the only redaction. The SDK works this way by design. - privacy/network: new "A filter replaces the built-in redaction" section. It lists what the default sanitizer redacts (checked against NetworkDataSanitizer), warns that installing a filter turns it off, and shows how to keep it by calling NetworkDataSanitizer.sanitize(event) inside the filter. - network, configuration/overview: point to the section. The option row now says a manifest filter counts too. - privacy/network, logs, breadcrumbs: the manifest sections claimed the filter "is in force from the very first captured event". That is not true on current releases, because the manifest filter is installed on a background thread after capture starts. They now say only what holds: the SDK installs it itself during launch, and with auto-init a filter set in Application.onCreate misses what was captured before the call. They also advise using either the code or the manifest filter, not both. - cspell: allow "apikey". 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I79bac610db9fed56d3158acabb58af656da1cc49 --- cspell.json | 1 + docs/sdk/android/configuration/overview.mdx | 2 +- docs/sdk/android/network.mdx | 1 + docs/sdk/android/privacy/breadcrumbs.mdx | 9 ++- docs/sdk/android/privacy/logs.mdx | 9 ++- docs/sdk/android/privacy/network.mdx | 65 ++++++++++++++++++++- 6 files changed, 77 insertions(+), 10 deletions(-) diff --git a/cspell.json b/cspell.json index 943ab37..78fa7ea 100644 --- a/cspell.json +++ b/cspell.json @@ -9,6 +9,7 @@ "SIGSEGV", "uncatchable", "unredacted", + "apikey", "zstd", "dedup", "sourcebundle", diff --git a/docs/sdk/android/configuration/overview.mdx b/docs/sdk/android/configuration/overview.mdx index 3eac9ca..63511e7 100644 --- a/docs/sdk/android/configuration/overview.mdx +++ b/docs/sdk/android/configuration/overview.mdx @@ -129,7 +129,7 @@ Bugsee.launch(this, "", options); | `CaptureNetworkOnLaunch` | `com.bugsee.option.capture.network.on-launch` | boolean | `false` | Subscribe the network provider during `launch()` instead of when capture starts, so requests issued during app startup are not missed. Costs a few extra milliseconds on the launching thread. *(7.1.0)* | | `CaptureNetworkBodySizeLimit` | `com.bugsee.option.capture.network.body-size-limit` | int (bytes) | `20480` | Maximum captured request/response body size, in bytes. | | `CaptureNetworkBodyWithoutType` | `com.bugsee.option.capture.network.body-without-type` | boolean | `false` | Also attach request/response bodies that have no declared content type; otherwise only textual bodies are kept. | -| `CaptureNetworkUseDefaultSanitizer` | `com.bugsee.option.capture.network.default-sanitizer` | boolean | `true` | Auto-redact known sensitive keys (PII) in URL query parameters, HTTP headers, and JSON bodies. Applies only when no custom network event filter is set. | +| `CaptureNetworkUseDefaultSanitizer` | `com.bugsee.option.capture.network.default-sanitizer` | boolean | `true` | Auto-redact known sensitive keys (PII) in URL query parameters, HTTP headers, and JSON bodies. Applies only when no network event filter is set, in code or in the manifest. | | `CaptureViewHierarchy` | `com.bugsee.option.capture.view-hierarchy` | boolean | `true` | Capture the view-hierarchy snapshot for reports. | | `CaptureBreadcrumbs` | `com.bugsee.option.capture.breadcrumbs` | boolean | `false` | Capture the breadcrumb trail of user and system events. | | `CaptureBreadcrumbsExtras` | `com.bugsee.option.capture.breadcrumbs.extras` | boolean | `false` | Also attach the raw `Intent` extras of captured system-event broadcasts to each breadcrumb. | diff --git a/docs/sdk/android/network.mdx b/docs/sdk/android/network.mdx index 13d7c15..dacc713 100644 --- a/docs/sdk/android/network.mdx +++ b/docs/sdk/android/network.mdx @@ -160,6 +160,7 @@ Notes on the filter shape: - Event types are `NetworkEvent` / `LogEvent` in `com.bugsee.library.contracts`. - Mutators (`setUrl`, `setMethod`, `setBody`, headers, etc.) and `getBodyAbsenceReason()` are available. - The filter applies uniformly to events coming from every network extension — OkHttp, Ktor 2, Ktor 3, and Cronet all feed the same pipeline. +- Installing a filter turns off the built-in redaction of credentials (`Authorization`, cookies, `password` and `token` fields); your filter must redact them, or call `NetworkDataSanitizer.sanitize(event)` to keep the built-in redaction. See [Privacy → Network traffic](/sdk/android/privacy/network#a-filter-replaces-the-built-in-redaction). See also the [Logs page](/sdk/android/logs) for the matching `setLogEventFilter(...)` API. diff --git a/docs/sdk/android/privacy/breadcrumbs.mdx b/docs/sdk/android/privacy/breadcrumbs.mdx index 3971317..81d966e 100644 --- a/docs/sdk/android/privacy/breadcrumbs.mdx +++ b/docs/sdk/android/privacy/breadcrumbs.mdx @@ -171,8 +171,10 @@ Bugsee.setBreadcrumbFilter { crumb, callback -> You can also point Bugsee at a breadcrumb filter from `AndroidManifest.xml`, with no code. Add a `com.bugsee.filter.breadcrumb` `` whose value is a class that implements `EventFilter` and has a public no-arg -constructor. The benefit: the filter is in force from the very first captured -event, even under auto-initialization, before any of your own code runs. +constructor. Bugsee installs it itself during 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. ```xml @@ -231,7 +233,8 @@ class MyBreadcrumbFilter : EventFilter { A filter set in code with `Bugsee.setBreadcrumbFilter(...)` takes precedence -over the manifest one. Because the class is referenced only by name, keep it +over the manifest one; use one or the other, not both. Because the class is +referenced only by name, keep it from R8 — annotate it `@Keep` or add `-keep class com.example.MyBreadcrumbFilter { (); }`. The same mechanism is available for [network events](/sdk/android/privacy/network#declaring-the-filter-in-the-manifest) diff --git a/docs/sdk/android/privacy/logs.mdx b/docs/sdk/android/privacy/logs.mdx index 84c8299..27fd216 100644 --- a/docs/sdk/android/privacy/logs.mdx +++ b/docs/sdk/android/privacy/logs.mdx @@ -77,8 +77,10 @@ Bugsee.setLogEventFilter { log, callback -> You can also point Bugsee at a log filter from `AndroidManifest.xml`, with no code. Add a `com.bugsee.filter.log-event` `` whose value is a class that implements `EventFilter` and has a public no-arg constructor. -The benefit: the filter is in force from the very first captured event, even -under auto-initialization, before any of your own code runs. +Bugsee installs it itself during 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, including logcat lines read before then. ```xml @@ -135,7 +137,8 @@ class MyLogFilter : EventFilter { A filter set in code with `Bugsee.setLogEventFilter(...)` takes precedence over -the manifest one. Because the class is referenced only by name, keep it from R8 +the manifest one; use one or the other, not both. Because the class is +referenced only by name, keep it from R8 — annotate it `@Keep` or add `-keep class com.example.MyLogFilter { (); }`. The same mechanism is available for [network events](/sdk/android/privacy/network#declaring-the-filter-in-the-manifest) diff --git a/docs/sdk/android/privacy/network.mdx b/docs/sdk/android/privacy/network.mdx index bdb3228..260305b 100644 --- a/docs/sdk/android/privacy/network.mdx +++ b/docs/sdk/android/privacy/network.mdx @@ -89,6 +89,61 @@ Bugsee.setNetworkEventFilter { event, callback -> +### 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 ``: + +- **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 or form bodies:** keys such as `pass`, `pin`, + `ssn`, `cvv`, `card_number`, `private_key`, `sid` and presigned-URL + signatures. +- **Any header, query or body key** whose name contains `password`, `passwd`, + `passcode`, `secret`, `token`, `session` or `apikey` / `api_key` / `api-key`. +- Sensitive query values quoted in error messages. + +It also removes `user:password@` credentials from URLs and error messages. + +:::warning[Installing a network filter turns this off] +Once a network filter is installed, either with `Bugsee.setNetworkEventFilter` +or [in the manifest](#declaring-the-filter-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. +::: + +To keep the built-in redaction and add your own, call +`NetworkDataSanitizer.sanitize(event)` (package +`com.bugsee.library.shared.security.privacy`) at the start of your filter: + + + + +```java +Bugsee.setNetworkEventFilter((event, callback) -> { + NetworkDataSanitizer.sanitize(event); // built-in redaction + // ...your own redaction... + callback.run(event); +}); +``` + + + + +```kotlin +Bugsee.setNetworkEventFilter { event, callback -> + NetworkDataSanitizer.sanitize(event) // built-in redaction + // ...your own redaction... + callback.run(event) +} +``` + + + + Capture from OkHttp 3/4, Ktor 2/3, and Cronet is wired automatically by the Bugsee Gradle plugin through the matching [extension modules](/sdk/android/extensibility/bugsee-extensions) — no manual interceptor @@ -99,8 +154,10 @@ registration is required. You can also point Bugsee at a network filter from `AndroidManifest.xml`, with no code. Add a `com.bugsee.filter.network-event` `` whose value is a class that implements `EventFilter` and has a public no-arg -constructor. The benefit: the filter is in force from the very first captured -event, even under auto-initialization, before any of your own code runs. +constructor. Bugsee installs it itself during 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). ```xml @@ -157,7 +214,9 @@ class MyNetworkFilter : EventFilter { A filter set in code with `Bugsee.setNetworkEventFilter(...)` takes precedence -over the manifest one. Because the class is referenced only by name, keep it +over the manifest one; use one or the other, not both. A manifest filter also +[replaces the built-in redaction](#a-filter-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 { (); }`. The same mechanism is available for [logs](/sdk/android/privacy/logs#declaring-the-filter-in-the-manifest) From 5911f196dd85a3f5694b3fa169bba4bf5489bb2a Mon Sep 17 00:00:00 2001 From: Alexey Karimov Date: Thu, 24 Sep 2026 09:54:33 +0500 Subject: [PATCH 2/2] docs(android): tighten the network redaction section MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Review follow-up: - Clearing the filter turns the default sanitizer back on only if CaptureNetworkUseDefaultSanitizer is still enabled. - The section now notes the URL-encoded replacement (%3Credacted%3E), that key matching is case-insensitive, and that key: value line bodies are covered too. - The manifest pages now say the filter is installed "as part of launch". 🤖 Generated with [Claude Code](https://claude.com/claude-code) Change-Id: I4be5e232aab25b3cb53b335fbf72312762cc23d2 --- cspell.json | 1 + docs/sdk/android/privacy/breadcrumbs.mdx | 2 +- docs/sdk/android/privacy/logs.mdx | 2 +- docs/sdk/android/privacy/network.mdx | 17 ++++++++++------- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/cspell.json b/cspell.json index 78fa7ea..06a2e15 100644 --- a/cspell.json +++ b/cspell.json @@ -10,6 +10,7 @@ "uncatchable", "unredacted", "apikey", + "Credacted", "zstd", "dedup", "sourcebundle", diff --git a/docs/sdk/android/privacy/breadcrumbs.mdx b/docs/sdk/android/privacy/breadcrumbs.mdx index 81d966e..abc3bba 100644 --- a/docs/sdk/android/privacy/breadcrumbs.mdx +++ b/docs/sdk/android/privacy/breadcrumbs.mdx @@ -171,7 +171,7 @@ Bugsee.setBreadcrumbFilter { crumb, callback -> You can also point Bugsee at a breadcrumb filter from `AndroidManifest.xml`, with no code. Add a `com.bugsee.filter.breadcrumb` `` whose value is a class that implements `EventFilter` and has a public no-arg -constructor. Bugsee installs it itself during launch, so it does not depend on +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. diff --git a/docs/sdk/android/privacy/logs.mdx b/docs/sdk/android/privacy/logs.mdx index 27fd216..0e4a0f6 100644 --- a/docs/sdk/android/privacy/logs.mdx +++ b/docs/sdk/android/privacy/logs.mdx @@ -77,7 +77,7 @@ Bugsee.setLogEventFilter { log, callback -> You can also point Bugsee at a log filter from `AndroidManifest.xml`, with no code. Add a `com.bugsee.filter.log-event` `` whose value is a class that implements `EventFilter` and has a public no-arg constructor. -Bugsee installs it itself during launch, so it does not depend on when your +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, including logcat lines read before then. diff --git a/docs/sdk/android/privacy/network.mdx b/docs/sdk/android/privacy/network.mdx index 260305b..2723db7 100644 --- a/docs/sdk/android/privacy/network.mdx +++ b/docs/sdk/android/privacy/network.mdx @@ -93,13 +93,14 @@ Bugsee.setNetworkEventFilter { event, callback -> Without a filter, Bugsee runs its default sanitizer on every network event (the `CaptureNetworkUseDefaultSanitizer` option, on by default). It replaces -these values with ``: +these values with `` (`%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 or form bodies:** keys such as `pass`, `pin`, - `ssn`, `cvv`, `card_number`, `private_key`, `sid` and presigned-URL - signatures. +- **URL query parameters and JSON, form-encoded or `key: value` line bodies:** + keys such as `pass`, `pin`, `ssn`, `cvv`, `card_number`, `private_key`, `sid` + and presigned-URL signatures. - **Any header, query or body key** whose name contains `password`, `passwd`, `passcode`, `secret`, `token`, `session` or `apikey` / `api_key` / `api-key`. - Sensitive query values quoted in error messages. @@ -112,7 +113,8 @@ or [in the manifest](#declaring-the-filter-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. +`Bugsee.setNetworkEventFilter(null)` turns the default sanitizer back on, +unless you disabled `CaptureNetworkUseDefaultSanitizer`. ::: To keep the built-in redaction and add your own, call @@ -154,10 +156,11 @@ registration is required. You can also point Bugsee at a network filter from `AndroidManifest.xml`, with no code. Add a `com.bugsee.filter.network-event` `` whose value is a class that implements `EventFilter` and has a public no-arg -constructor. Bugsee installs it itself during launch, so it does not depend on +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). +captured before the call (those events get the built-in redaction instead, +when it is enabled). ```xml