diff --git a/cspell.json b/cspell.json index 943ab37..06a2e15 100644 --- a/cspell.json +++ b/cspell.json @@ -9,6 +9,8 @@ "SIGSEGV", "uncatchable", "unredacted", + "apikey", + "Credacted", "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..abc3bba 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 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. ```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..0e4a0f6 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 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. ```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..2723db7 100644 --- a/docs/sdk/android/privacy/network.mdx +++ b/docs/sdk/android/privacy/network.mdx @@ -89,6 +89,63 @@ 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 `` (`%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: 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. + +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, +unless you disabled `CaptureNetworkUseDefaultSanitizer`. +::: + +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 +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. 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 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). ```xml @@ -157,7 +217,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)