Skip to content

buildSessionId() falls back to Date.now() + Math.random() when crypto.randomUUID is unavailable - weak uniqueness causes file name collisions in concurrent exports #1707

Description

@anshul23102

Problem

src/lib/ffmpeg.ts generates session IDs to isolate FFmpeg file names:

function buildSessionId(): string {
  if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
    return crypto.randomUUID();
  }
  return `${Date.now()}-${Math.random().toString(16).slice(2)}`;
}

The fallback path uses Date.now() (millisecond precision) combined with
Math.random(). In environments where crypto.randomUUID is unavailable
(older browsers, certain SSR contexts), two concurrent exports started within
the same millisecond can generate the same session ID. This causes their
temporary FFmpeg files (input_<id>.mp4, output_<id>.mp4) to collide,
leading to one export overwriting the other's input file mid-process.

crypto.randomUUID is available in all modern browsers (Chrome 92+, Firefox
95+, Safari 15.4+). However, the fallback is not secure and not collision-
resistant for concurrent use.

Impact

  • In concurrent export scenarios, file name collision causes one export to
    read corrupted input data from the other export's file.
  • The resulting export produces a corrupted or mismatched output video with
    no error message.

Suggested Fix

  1. Remove the fallback entirely and require crypto.randomUUID. All browsers
    listed in Reframe's support matrix (Chrome 90+, Firefox 89+, Safari 15+)
    support crypto.randomUUID.
  2. If the fallback must stay, use a counter-based approach that guarantees
    uniqueness within the session:
    let counter = 0;
    function buildSessionId(): string {
      return `${Date.now()}-${++counter}-${Math.random().toString(36).slice(2)}`;
    }
  3. Add a startup check that throws a clear error if crypto.randomUUID is
    absent rather than silently degrading to a weaker ID scheme.

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions