Security Architecture & Threat Model
Security is a foundational design pillar of CopyPatch. Unlike traditional CMS platforms that store arbitrary HTML and expose wide attack surfaces, CopyPatch enforces strict architectural boundaries to eliminate stored XSS, prevent brute-force attacks, and isolate editing sessions.
1. Strict Plain-Text Invariant (Zero XSS)
CopyPatch accepts, validates, and stores plain-text strings only:
- HTML tags (e.g.
<script>,<iframe>,<img onerror>) are never parsed or executed as active DOM nodes. - React's standard text interpolation safely renders all copy as text nodes (0%
dangerouslySetInnerHTML). - Server-side validators normalize Unicode whitespace and reject payloads larger than 64 KB.
2. Same-Origin Boundary & Origin Validation
CopyPatch v2 runs exclusively inside the host application's origin:
- The embedded API rejects any mutating request whose
Originheader does not exactly match the host domain. - CopyPatch does not emit CORS allowlist headers or support insecure cross-origin proxy setups.
3. Argon2id Cryptographic Parameters
The built-in passphrase strategy uses Argon2id (RFC 9106 standard) to resist GPU, ASIC, and side-channel brute-force attacks:
| Parameter | Value | Rationale |
|---|---|---|
| Algorithm | Argon2id | Hybrid defense against both side-channel and GPU-accelerated brute-force attacks. |
| Memory Cost (m) | 19 MiB (19456 KiB) | Forces high dedicated RAM allocation per candidate guess on attack hardware. |
| Time Cost (t) | 2 iterations | Delivers robust computational workload without introducing perceivable login latency. |
| Parallelism (p) | 1 lane | Ensures deterministic, predictable execution across single-core cloud environments. |
| Salt Length | 32 bytes (256-bit) | Cryptographically random salt generated via node:crypto for every hash. |
4. Hardened Session & Token Handling
- High-Entropy Tokens: Session tokens are generated with 256-bit cryptographic entropy (
crypto.randomBytes(32)). - Token Hashing at Rest: Storage adapters only receive and persist SHA-256 hashes of session and rate-limit identifiers. Even if a raw database file is exposed, session tokens cannot be recovered.
- Secure Cookies: Transmitted with
HttpOnly,SameSite=Strict, andSecureflags. Over HTTPS, the__Host-prefix is enforced to prevent subdomain injection.
5. Dual-Token CSRF Protection
All state-changing endpoints (POST, PUT, DELETE) require two independent verification factors:
- The browser's automated
HttpOnlysession cookie. - A unique CSRF token stored in JavaScript memory and passed via the custom
x-copypatch-csrfheader.
Threat Analysis Matrix
| Threat Vector | Severity | CopyPatch Architectural Defense |
|---|---|---|
| Stored XSS | Critical | Strict plain-text normalizers; standard React text node interpolation; zero HTML execution. |
| CSRF Attacks | High | Exact same-origin checking + SameSite=Strict cookies + required x-copypatch-csrf header. |
| Brute-Force Login | High | Persistent IP/key rate limiting + 19 MiB Argon2id memory hardness. |
| SQL Injection | Critical | 100% parameterized queries in better-sqlite3 and pg; strict alphanumeric key regex validation. |
| Session Disclosure | High | SHA-256 token hashing in storage; HttpOnly + Secure + __Host- prefixes. |
| Revision Overwrites | Medium | Atomic compare-and-swap (CAS) validation on draft and published revision counters. |
Recommended Content Security Policy (CSP)
We recommend configuring the following CSP header on your production server:
HTTP Response Header
Content-Security-Policy: default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self';