# Security and privacy Patterns, flags, replacement templates, subjects and imported projects are untrusted. - Syntax and execution use separate workers. - Regex execution never occurs on the UI thread. - Timeout, crash and cancellation terminate the worker. - A terminated worker is never reused. - Pattern, subject, replacement/list template, match, capture and output sizes are bounded. - PCRE2 adds native match-step, depth and heap caps. Its C ABI returns only caller-owned bounded records and releases code, match data and match context on every exit path. - PCRE2 automatic-callout tracing is a separate ABI and worker path. It copies only complete fixed records and bounded mark text, stops matching at the 50,000-event or 10 MiB serialized trace cap, and is killed on timeout, cancellation or crash. - PCRE2 runs only in mandatory UTF/UCP mode. Exact UTF-8 byte boundaries are normalized to editor UTF-16 offsets; lone surrogates are rejected instead of being silently replaced by browser encoding. - Replacement templates are strings; executable callbacks are unavailable. - Replacement/list token decorations, rows, chips, diagnostics and list evaluation work have separate presentation/operation caps; incomplete list results cannot be exported. - Per-match replacement mapping executes no user code and is capped at 200 matches, 2,000 materialized contributions and 50,000 token evaluations. - Imported JSON is aggregate-size-bounded before parsing, then field-validated and never evaluated or auto-run. Export and IndexedDB save apply the same 32 MiB aggregate UTF-8 document bound before materialization or persistence. - Project and standalone-suite test subjects are not exported by default, and unit-test subjects require a separate opt-in before IndexedDB persistence. - Unit-test add, update, clone and append-import paths share 1,000-case and 32 MiB aggregate state caps. - Unit-test assertion diagnostics never stringify complete large values and retain at most 2 KiB UTF-8 per case. Oversized replacement output is not copied into an exact current-result draft. - Corpus file input is local, recognized UTF-8 text only. It is bounded before decoding, rejects NUL/binary input, runs sequentially in a dedicated cancellable supervisor and never modifies source files. - Corpus JSON/CSV/NDJSON summaries never contain source, capture-sample or applied-output content. CSV cells are formula-injection protected. Local UI previews are explicitly bounded. Applied files require an explicit content-export acknowledgement; names are normalized against archive path traversal and collisions. Incomplete applied output cannot be downloaded or included in the all-document ZIP, whose bytes have a separate hard limit. - Corpus documents, contents, outputs and results are never placed in project JSON or IndexedDB. Schema-v1 imports that attempt to inject corpus payloads are rejected. - ECMAScript growth analysis preflights repetition count and UTF-8 bytes before allocating a generated string. The analysis worker is terminated on timeout, cancellation or crash; replacement timing also preflights its output bound. Analysis settings and results are neither persisted nor uploaded. - Generated-case synthesis runs in its own killable worker under AST, depth, attempt, repetition and UTF-8 byte caps. Labels come only from bounded requests to the selected real engine worker; a wrong outcome, timeout, crash, cancellation or compile rejection is never converted into a verified case. Settings, discarded candidates and unselected results are ephemeral and never uploaded. - Imported generated-test provenance is accepted only for the exact supported generator id/version and must agree with the test assertion outcome. Unknown provenance fields and future versions are rejected; editing a case removes its provenance. - ECMAScript formatting consumes only exact accepted regexpp literal-token ranges and never treats PCRE2 as ECMAScript. Source/candidate syntax and execution use separate killable workers; compile failure, truncation, timeout asymmetry, engine-identity drift, incomplete tests or any semantic difference fails closed. Preview/results are ephemeral and apply requires an explicit confirmation. - Subject minimization rejects lone surrogates, caps input at 1 MiB UTF-8, evaluation count at 2,000 and aggregate wall time at 60 seconds. Each predicate check runs in the selected killable engine worker. Timeout, crash, cancellation and worker error remain distinct; truncated results fail closed. Subjects and results are ephemeral and never uploaded or persisted. - No backend, uploads, telemetry, remote corpus URL, CDN, remote font, `eval`, `Function`, arbitrary command line or unsafe HTML rendering exists. The PCRE2-enabled build needs a CSP equivalent to: ```text default-src 'self'; script-src 'self' 'wasm-unsafe-eval'; worker-src 'self' blob:; connect-src 'self'; img-src 'self' data:; font-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none'; frame-src 'none'; base-uri 'none'; form-action 'none'; ``` The Toolbox shell currently requires inline styles. Corpus ZIP generation and PCRE2 use self-hosted modules and local workers under the existing `worker-src` policy. Broad `unsafe-eval` is not required. Report vulnerabilities privately to the repository owner before public issue details are posted.