142 lines
6.0 KiB
Markdown
142 lines
6.0 KiB
Markdown
# 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:
|
|
|
|
```text
|
|
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:
|
|
|
|
```text
|
|
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.
|