Skip to content

Commit 6e67955

Browse files
martinhaintzmar-haivaind
authored
feat(flutter): update screenshots and session replay with masking options (#11930)
* add masking options * minor arrangement changes * add specific intro for screenshot and session replay * Update docs/platforms/flutter/session-replay/index.mdx Co-authored-by: Ivan Dlugos <[email protected]> --------- Co-authored-by: Martin Haintz <[email protected]> Co-authored-by: Ivan Dlugos <[email protected]>
1 parent fdbdf00 commit 6e67955

File tree

3 files changed

+75
-39
lines changed

3 files changed

+75
-39
lines changed

docs/platforms/flutter/session-replay/index.mdx

+6-39
Original file line numberDiff line numberDiff line change
@@ -57,50 +57,17 @@ Sampling allows you to control how much of your website's traffic will result in
5757

5858
Sampling starts as soon as a session begins. The `sessionSampleRate` is then evaluated. If the session is sampled, replay recording will start immediately. If not, `onErrorSampleRate` will be evaluated. If the session is sampled at this point, the replay will be buffered and will only be uploaded to Sentry if an error occurs.
5959

60-
## Privacy
60+
## Redact Session Replay via `masking`
6161

62-
The SDK is recording and aggressively redacting (masking) all `Text`, `EditableText`, and `Image` widgets.
63-
Masking in the Sentry Flutter SDK is based on Widget *types*, e.g. `Image`, not the string representation of the type (i.e. we check whether
64-
a `widgetInstance` should be masked by checking `if (widgetInstance is Image)` instead of `if (widgetInstance.runtimeType == 'Image')`).
65-
This means we can ensure masking works regardless of obfuscation in release builds and also works for subclasses.
66-
However, it also means we can only automatically mask widgets that are part of the Flutter SDK itself.
62+
By default, the SDK is recording and aggressively redacting (masking) all `Text`, `EditableText`, and `Image` widgets for <PlatformLink to="/session-replay/">`Session Replay`</PlatformLink>. To modify or disable this behavior, use the `options.experimental.privacy` parameter.
6763

6864
<Alert level="warning">
69-
We cannot mask widgets defined in various 3rd-party packages (because the type is not known in the Sentry Flutter SDK),
70-
even though many should be masked.
71-
72-
Therefore, you need to consider the widgets your application uses and ensure they're masked correctly with custom masking rules.
73-
Examples of widgets that usually should be masked include (but are not limited to): VideoPlayer, WebView, Chart, etc.
65+
Modifying this parameter will also affect `masking` for
66+
<PlatformLink to="/enriching-events/screenshots/">`Screenshots`</PlatformLink>
67+
.
7468
</Alert>
7569

76-
You can tune this and add custom masking rules to fit your needs by adjusting the configuration in `options.experimental.replay`.
77-
For example, you can explicitly mask or unmask widgets by type,
78-
or you can even have a callback to decide whether a specific widget instance should be masked:
79-
80-
```dart
81-
options.experimental.replay.mask<IconButton>();
82-
options.experimental.replay.unmask<Image>();
83-
options.experimental.replay.maskCallback<Text>(
84-
(Element element, Text widget) =>
85-
(widget.data?.contains('secret') ?? false)
86-
? SentryMaskingDecision.mask
87-
: SentryMaskingDecision.continueProcessing);
88-
```
89-
90-
You can find more details in the documentation for each method.
91-
92-
<Note>
93-
94-
If you find that data isn't being redacted with the default settings, please let us know by creating a [GitHub issue](https://github.com/getsentry/sentry-dart/issues/new?template=BUG_REPORT.yml).
95-
96-
</Note>
97-
98-
To disable redaction altogether (not to be used on applications with sensitive data):
99-
100-
```dart
101-
options.experimental.replay.maskAllText = false;
102-
options.experimental.replay.maskAllImages = false;
103-
```
70+
<PlatformContent includePath="replay/privacy-configuration" />
10471

10572
## Error Linking
10673

platform-includes/enriching-events/attach-screenshots/flutter.mdx

+11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,17 @@ await SentryFlutter.init(
1313
);
1414
```
1515

16+
## Redact Screenshots via `masking`
17+
18+
The masking feature is by default disabled for Screenshots. To enable masking, use the `options.experimental.privacy` parameter.
19+
20+
<Alert level="warning">
21+
Modifying this parameter will also affect `masking` for{" "}
22+
<PlatformLink to="/session-replay/">`Session Replay`</PlatformLink>.
23+
</Alert>
24+
25+
<PlatformContent includePath="replay/privacy-configuration" />
26+
1627
## Filtering Screenshots
1728

1829
You can filter your screenshots by using the `beforeScreenshot` callback, which is called before attaching a screenshot to an event. By default, the callback returns `true` which means that all screenshots are attached.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
Masking in the Sentry Flutter SDK is based on Widget _types_, e.g. `Image`, not the string representation of the type (i.e. we check whether
2+
a `widgetInstance` should be masked by checking `if (widgetInstance is Image)` instead of `if (widgetInstance.runtimeType == 'Image')`).
3+
This means we can ensure masking works regardless of obfuscation in release builds and also works for subclasses.
4+
However, it also means we can only automatically mask widgets that are part of the Flutter SDK itself.
5+
6+
<Alert level="warning">
7+
We cannot mask widgets defined in various 3rd-party packages (because the type is not known in the Sentry Flutter SDK),
8+
even though many should be masked.
9+
10+
Therefore, you need to consider the widgets your application uses and ensure they're masked correctly with custom masking rules.
11+
Examples of widgets that usually should be masked include (but are not limited to): VideoPlayer, WebView, Chart, etc.
12+
13+
</Alert>
14+
15+
You can tune this and add custom masking rules to fit your needs by adjusting the configuration in `options.experimental.privacy`.
16+
For example, you can explicitly mask or unmask widgets by type,
17+
or you can even have a callback to decide whether a specific widget instance should be masked:
18+
19+
```dart
20+
options.privacy.mask<IconButton>();
21+
options.privacy.unmask<Image>();
22+
options.privacy.maskCallback<Text>(
23+
(Element element, Text widget) =>
24+
(widget.data?.contains('secret') ?? false)
25+
? SentryMaskingDecision.mask
26+
: SentryMaskingDecision.continueProcessing);
27+
```
28+
29+
### `maskAllText`
30+
31+
Mask all text content. Draws a rectangle of text bounds with text color on top. Currently, only `Text` and `EditableText` Widgets are masked.
32+
33+
### `maskAllImages`
34+
35+
Mask content of all images. Draws a rectangle of image bounds with image's dominant color on top. Currently, only `Image` widgets are masked.
36+
37+
### `maskAssetImages`
38+
39+
Mask asset images coming from the root asset bundle.
40+
41+
### `mask<T extends Widget>()`
42+
43+
Mask given widget type `T` (or subclasses of `T`) in the screenshot. Note: masking rules are called in the order they're added so if a previous rule already makes a decision, this rule won't be called.
44+
45+
You can find more details in the documentation for each method.
46+
47+
<Note>
48+
49+
If you find that data isn't being masked with the default settings, please let us know by creating a [GitHub issue](https://github.com/getsentry/sentry-dart/issues/new?template=BUG_REPORT.yml).
50+
51+
</Note>
52+
53+
To disable masking for <PlatformLink to="/enriching-events/screenshots/">`Screenshots`</PlatformLink> and <PlatformLink to="/session-replay/">`Session Replay`</PlatformLink> (not to be used on applications with sensitive data):
54+
55+
```dart
56+
options.experimental.privacy.maskAllText = false;
57+
options.experimental.privacy.maskAllImages = false;
58+
```

0 commit comments

Comments
 (0)