Skip to content

feat(session-replay): upload replay envelope from the native crash daemon#1809

Draft
tustanivsky wants to merge 7 commits into
masterfrom
feat/session-replay-prod
Draft

feat(session-replay): upload replay envelope from the native crash daemon#1809
tustanivsky wants to merge 7 commits into
masterfrom
feat/session-replay-prod

Conversation

@tustanivsky

@tustanivsky tustanivsky commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

This PR adds Session Replay product support to the native backend. When a downstream SDK (e.g. sentry-unreal) has staged a recorded clip on disk, the crash daemon now builds a replay_video envelope from it and performs an upload so the clip becomes a first-class Session Replay in Sentry, linked to the crash instead of only being available as a file attachment.

Key Changes

  • New internal sentry__session_replay_flush_pending(): scans <database>/replays/ for embedder-staged clips (a replay-<id>.json metadata sidecar + its .mp4), builds the replay_event + replay_recording + video into a replay_video envelope, and hands it to the transport.
  • Scope/trace sync: the replay event reuses the crash event's already-applied scope (tags, contexts, release, environment, user, sdk) and lifts its trace_id, read back from <run>/__sentry-event. This makes the replay carry the same tags as the crash and correlate via the same trace.
  • Wired into the crash daemon: after the crash report is captured, the daemon calls flush_pending out-of-process, so the replay is sent in the same session as the crash (no next-launch step).
  • No new public API - the embedder communicates entirely through the on-disk replays/ convention.

Known Limitations

  • Native daemon backend only - not wired for crashpad / breakpad / inproc.

Related items

#skip-changelog

@github-actions

github-actions Bot commented Jun 20, 2026

Copy link
Copy Markdown
Messages
📖 Do not forget to update Sentry-docs with your feature once the pull request gets approved.

Generated by 🚫 dangerJS against cbab847

@tustanivsky tustanivsky force-pushed the feat/session-replay-prod branch from 154ce2f to b437853 Compare June 25, 2026 07:30
@tustanivsky tustanivsky changed the title feat: add Session Replay envelope capture utility feat(session-replay): upload replay envelope from the native crash daemon Jun 29, 2026
Comment on lines +313 to +316
sentry_value_get_by_key(meta, "videoFilename"));
sentry_path_t *mp4_path = (video_filename && video_filename[0])
? sentry__path_join_str(dir, video_filename)
: NULL;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing path containment for videoFilename from replay JSON sidecar allows reading files outside the replays directory

The videoFilename read from an embedder-written .json sidecar in <database>/replays/ is passed to sentry__path_join_str with no .. or absolute-path containment check, so a crafted sidecar can make the daemon read an arbitrary file and embed it in the uploaded replay_video envelope. Normalize and confirm the resolved path stays inside the replays directory before reading it.

Evidence
  • video_filename is taken verbatim from meta["videoFilename"] (sentry_session_replay.c:312-313), sourced from a JSON file on disk in <database>/replays/.
  • It is passed directly to sentry__path_join_str(dir, video_filename) (line 315) with no normalization or prefix check.
  • sentry__path_join_str (sentry_path_unix.c:279) returns any other starting with / as an absolute path and never strips .. components, so traversal/absolute escape is possible.
  • build_replay_envelope then reads the full file via sentry__path_read_to_buffer and embeds it as the replay_video blob dispatched through the transport.
  • Impact is limited: exploitation requires an attacker who can already write into <database>/replays/, and the file is uploaded to the developer's own configured Sentry DSN rather than an attacker endpoint, so this is a defense-in-depth containment gap.

Identified by Warden security-review · G88-YYA

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant