Files
av-tools/docs/SECURITY.md

6.0 KiB

Security and privacy

Trust boundary

Imported media, filenames, container metadata, tags, chapters, subtitles, attachments, codec logs, project JSON and Toolbox context are untrusted. FFmpeg parsing occurs in a worker but still consumes memory/CPU in the user's browser. The application cannot make a malicious codec safe; it limits exposure and keeps cleanup/recovery explicit.

The supported product has:

  • no upload or processing backend;
  • no telemetry, analytics or third-party runtime script;
  • no remote-media protocol or automatic external fetch;
  • no shell/native command execution;
  • no arbitrary FFmpeg command input;
  • no persistent source copy in the current application.

Browser extension, operating-system, reverse-proxy and compromised dependency behavior remain outside this boundary.

Paths and command construction

User names are display labels only. Virtual filesystem paths are generated from job ids plus sanitized, length-bounded basenames; separators, traversal, control characters, reserved names and collisions are handled centrally. Outputs must be declared in a typed plan before execution.

Commands are argument arrays assembled from discriminated operation/preset types. No shell parses them. Filters, metadata, concat lists, chapter metadata and subtitle values use syntax-specific escaping; one escaping routine is not reused across incompatible grammars. Capability requirements are checked before execution. Logs are line/byte bounded and local path-like names are redacted in exportable diagnostics.

Rendering and external URLs

Metadata is rendered as React text, never dangerouslySetInnerHTML. Subtitle text is parsed and rendered or sent through a generated local file; it is not inserted as HTML. Extracted URLs are inert text. The application does not open links from media automatically. No remote font is fetched. Contact-sheet labels mount only the same-origin, size/SHA-256-verified DejaVu asset and fail closed without drawtext; ASS burn-in uses packaged/system-generic font configuration only when the required local capability is available.

Preview/download URLs are blob: values made from local bytes. They are revoked on replacement, project close and unmount. Browser support for a container is not evidence that its contents are safe or fully decodable.

Resource controls

The administrator-adjustable defaults are product limits, not FFmpeg limits:

Limit Default
soft input warning 256 MiB
hard single input 1536 MiB
hard total input 1536 MiB
soft output estimate 512 MiB
hard output estimate 1024 MiB
concurrent FFmpeg jobs 1
scheduled operations in memory 8
timeline clips 100
streams per input 64
image dimension / pixel count 8192 / 67,108,864
generated outputs / contact cells 255 / 500
job runtime 4 hours

Before allocation, the application estimates source/output bytes, duration, resolution, frame/pixel work, passes, retained results and output count. Estimates are labelled as estimates. Hard-limit violations do not start; soft violations explain resolution/duration/output-count alternatives. The 255-output limit keeps a whole managed batch saveable in the 256-entry ZIP limit with an optional report. Memory-constrained devices receive stronger warnings only when a reliable browser signal exists.

WASM itself has a documented 2 GiB input ceiling; practical browser limits can be much lower, especially when input and output coexist. Archive/export and cache operations also enforce entry, total-size and path limits.

Workers and cancellation

Wrapper, core, pthread and waveform workers are same-origin or short-lived blob: workers created by trusted application code. OPFS caching currently uses asynchronous browser file handles rather than a separate storage worker. MT requires shared memory and cross-origin isolation. ST loads when isolation is absent. Cancelling FFmpeg terminates and discards its worker/core; a new instance is required before another job. Stale generations cannot commit a result.

Content Security Policy

Tested deployment policy target:

default-src 'self';
script-src 'self' 'wasm-unsafe-eval';
worker-src 'self' blob:;
connect-src 'self';
img-src 'self' blob: data:;
media-src 'self' blob:;
font-src 'self';
style-src 'self';
object-src 'none';
frame-src 'none';
frame-ancestors 'none';
base-uri 'none';
form-action 'none';

Do not replace 'wasm-unsafe-eval' with broad 'unsafe-eval'. All core assets are same-origin. media-src blob: is required for result/source previews. The exact headers, immutable Portal reference gap and active-worktree local patch are in docs/PORTAL_REQUIREMENTS.md.

Cross-origin isolation

MT needs secure HTTPS (localhost during development is acceptable), SharedArrayBuffer, and:

Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Resource-Policy: same-origin

Isolation affects every resource in the page. Do not weaken COEP or allow cross-origin dependencies merely to make MT load. The safe fallback is ST.

Dependency and vulnerability response

Exact runtime versions and core digests are recorded in SOURCE.md. Run npm audit, tests, real core smoke tests and legal review before an update. Core upgrades change a large native attack surface and require new capability snapshots, fixtures, checksums and browser tests.

Report vulnerabilities privately to the repository owner through the Gitea instance when possible. Do not attach sensitive media, credentials or an unredacted diagnostic log to a public issue. Include the app/core version, browser, mode, smallest synthetic reproduction, impact and cleanup result.