Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 22 additions & 3 deletions docs/website/configuration.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -297,9 +297,28 @@ Supported attributes:
- `data-bugdrop-redacted`
- `data-bugdrop-mask`

This is best-effort visual masking, not a data-loss-prevention or security boundary. BugDrop can only mask content it can measure in the page DOM. Unmarked sensitive information can still appear, and browser rendering limits can apply to canvas, image, video, iframe, SVG, shadow DOM, pseudo-element, and highly custom control content.

Selected-area screenshots are rendered to the selected dimensions and masks are translated into that crop, but the capture still runs client-side against the page DOM. Avoid screenshots entirely for pages where client-side screenshot rendering is unacceptable.
This is visual masking, not a data-loss-prevention or security boundary.
BugDrop can only mask content it can measure in the page DOM. Unmarked
sensitive information can still appear, and browser rendering limits can apply
to canvas, image, video, iframe, SVG, shadow DOM, pseudo-element, and highly
custom control content.

Masking works in full-page, selected-element, selected-area, and automatic
screenshot modes when BugDrop renders the page through its DOM screenshot path.
For selected-area captures, mask rectangles are translated into the selected
crop. For selected-element captures with surrounding context enabled, masks are
computed relative to the captured context element.

| Capture path | Automatic DOM masks | User preview | Manual redact tool | Limitation warning | Notes |
| --- | --- | --- | --- | --- | --- |
| Full page | Yes | Yes | Yes | Yes | Uses DOM screenshot rendering unless the page is too complex |
| Selected element | Yes | Yes | Yes | Yes | Masks are relative to the captured element or surrounding context |
| Selected area | Yes | Yes | Yes | Yes, scoped to the crop | Masks outside the selected crop are ignored |
| Automatic screenshot | Yes | No | No | No in the current UI | Use only when marked sensitive regions are stable and supported |
| Native viewport fallback | No | Yes | Yes | Existing unavailable-mask warning | Used for very complex pages; users must review manually |

Disable screenshots or use `data-screenshot="optional"` on pages where sensitive
pixels cannot be reliably enclosed by DOM boxes.

```html
<!-- Automatically attach a full-page screenshot -->
Expand Down
66 changes: 35 additions & 31 deletions docs/website/security.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ BugDrop is built with a privacy-first approach:

### Screenshot masking

You can mark sensitive elements so BugDrop visually covers them in supported screenshot modes. Add `data-bugdrop-redact` or `data-bugdrop-mask` to any element you want covered:
BugDrop supports developer-configured visual masking for screenshots. Add
`data-bugdrop-redact` or `data-bugdrop-mask` to any DOM element that should be
covered:

```html
<input type="email" data-bugdrop-redact />
Expand All @@ -92,46 +94,48 @@ You can mark sensitive elements so BugDrop visually covers them in supported scr
Supported explicit attributes are `data-bugdrop-redact`, `data-bd-redact`,
`data-bugdrop-redacted`, and `data-bugdrop-mask`.

When a user submits feedback, BugDrop plans redactions from matching DOM
elements, then paints an opaque rectangle over each target's measured bounding
box on supported captured PNGs. In manual screenshot flows, the masked image is
shown in the annotator preview so the user can audit it before submitting. In
automatic screenshot mode, BugDrop applies supported masks but submits without
showing the preview step.
For supported DOM-rendered captures, when masking succeeds, BugDrop records the
geometry of matching DOM elements, renders the screenshot, then paints opaque
rectangles over those measured boxes in the PNG. The submitted image contains
the black rectangles. If masking fails, BugDrop discards the screenshot instead
of uploading it. The original page DOM is not mutated.

Masking is best-effort visual coverage, not a data-loss-prevention or security
boundary. Users should still review screenshots before submitting when the manual
screenshot flow is enabled.
Masking is visual coverage, not data-loss prevention. BugDrop does not inspect
text or pixels to discover secrets. Developers must mark the sensitive regions
they control, and users should review manual screenshots before submitting.

**Inheritance.** When an ancestor has `data-bugdrop-mask`, the entire ancestor box is
masked as a single rectangle. Descendants do not get individual rectangles — this
prevents gaps from CSS `gap` or non-masked siblings inside a masked container.

**Built-in defaults.** These are always masked, with or without an explicit attribute:
**Built-in defaults.** In supported DOM-rendered screenshot paths, BugDrop
automatically masks these with or without an explicit attribute:

- `input[type="password"]`
- Any input with `autocomplete="cc-number"`, `cc-csc`, or `cc-exp`

**Known limitations:**

- Elements inside open Shadow DOM are traversed when the browser exposes the
shadow root. Closed Shadow DOM cannot be traversed; mark the host element if
the whole custom control should be covered.
- Iframe contents are not traversed. Mark the iframe element itself if the whole
embedded frame should be visually covered.
- BugDrop does not inspect pixels or text inside canvas, image, video, plugin,
or iframe content. Mark the containing DOM element if that entire region should
be visually covered.
- Mask rectangles are collected at the start of capture. If the page reflows or reveals
sensitive elements between collection and the moment `html-to-image` finishes
rendering, the mask may not cover the final pixels. Keep masked content stable during
the brief capture window.
- **Viewport capture fallback (very complex pages):** When the page exceeds the
full-page DOM-complexity threshold, BugDrop falls back to a screen-recording
capture (via the browser's `getDisplayMedia` API). That path captures the
visible viewport directly and does not apply element masks. If you rely on
masking, ensure the user is not capturing through this fallback when sensitive
elements are visible.
These defaults do not apply to native viewport capture or skipped/failed
screenshot paths.

| Surface | Behavior | Recommended control |
| --- | --- | --- |
| Regular DOM elements | Marked element box is covered | Mark the smallest stable container that fully encloses the sensitive content |
| Password and credit-card inputs | Covered automatically | No extra attribute required, but explicit marks are fine |
| Open Shadow DOM | Traversed when the browser exposes `shadowRoot` | Mark inner controls or the host |
| Closed Shadow DOM | Not traversed | Mark the host custom element |
| Iframes | Iframe internals are not traversed | Mark the iframe element if the whole embedded frame is sensitive |
| Canvas, image, SVG, video | Internal pixels are not inspected | Mark the element or a containing wrapper |
| Pseudo-elements and highly custom controls | Generated pixels are not inspected separately | Mark a stable wrapper around the whole control |
| Native viewport capture fallback | Element masks cannot be applied | Avoid viewport fallback on pages that require masking |

If a marked region includes embedded, media, or pixel-rendered content, BugDrop
covers the marked element box and warns the user in manual screenshot review
flows that it cannot inspect the internal pixels. Automatic screenshot mode
still applies supported masks, but it submits without showing a review step.

Mask rectangles are measured at capture start. If the page reflows or reveals
sensitive elements after that measurement but before rendering finishes, a mask
can become stale. Keep sensitive marked regions stable during capture.

The only network requests BugDrop makes are:

Expand Down
Loading