- Refine session and storage lifecycle handling - Improve VM extension architecture across server, shared, and WASM runtimes - Enhance synthetic gene mutation engine integration and parity guarantees - Align deterministic state progression between server and browser execution paths - Update configuration examples and deployment guidance - Expand architecture, API, threat model, privacy, and WASM build documentation - Refresh README with comprehensive project overview, operational workflows, browser integration details, storage backend documentation, and security model - Document v0.6.0 refactoring outcomes and design rationale - Improve consistency across documentation, configuration, and implementation This commit consolidates the v0.6.0 architectural refactoring effort, strengthening deterministic browser/server parity while improving maintainability, operational clarity, and project documentation.
6.6 KiB
ChronoSeal Threat Model
ChronoSeal is a cost-raising browser attestation layer. It makes replay, stale state reuse, and incomplete automation more expensive by requiring signed, continuous, deterministic browser-side state progression.
It is not a perfect bot blocker, CAPTCHA replacement, hardware attestation system, fraud engine, or identity provider.
Security Objectives
ChronoSeal aims to:
- reject stale or replayed heartbeat payloads
- reject heartbeats that do not maintain the server-issued mutation sequence
- bind heartbeat payloads to a browser-local Ed25519 session key
- make basic HTTP clients insufficient
- make browser automation maintain multiple synchronized state channels
- avoid detailed rejection feedback
- preserve privacy by avoiding persistent user identity state
Protected Assets
| Asset | Protection focus |
|---|---|
| Protected page/API access | Require live attestation before allowing continued access |
| Session continuity | Ensure each accepted heartbeat advances from the last accepted state |
| Server compute | Rate-limit and reject invalid clients without expensive application work |
| Protocol state | Protect hash-chain, salt, and mutation progression |
| User privacy | Avoid long-term tracking and detailed failure disclosure |
Trust Assumptions
ChronoSeal assumes:
- the server host and daemon process are trusted
- storage is trusted for session continuity
- TLS protects traffic in production
- browser clients can run JavaScript and WASM
- operators configure reverse proxy, filesystem permissions, and logs appropriately
ChronoSeal does not assume:
- the browser is honest
- WASM is a secure enclave
- mouse data proves human presence
- fingerprint values are unforgeable
- attackers cannot run a full browser
Attacker Levels
Level 1: Commodity HTTP Client
Examples:
curlrequests- scraper scripts without browser or WASM execution
Expected result:
- cannot produce valid signatures
- cannot maintain hash-chain state
- cannot execute mutation preview
- cannot produce accepted heartbeats
Level 2: Basic Headless Browser
Examples:
- Playwright
- Puppeteer
- Selenium
Expected result:
- can load JavaScript and WASM
- must preserve keypair, hash chain, salt, VM, and mutation state
- must generate plausible timing and mouse event windows
- silent rejection complicates debugging and scaling
Level 3: Stealth Automation
Examples:
- patched browser runtime
- synthetic event generation
- custom protocol client with WASM or Rust reimplementation
Expected result:
- can attempt full protocol implementation
- must still match canonical signing, hash progression, mutation parity, and timing
- must handle changing server-issued mutation programs
- receives limited failure feedback
Level 4: Resourced Browser Farm
Examples:
- real browsers
- realistic input devices
- human-assisted workflows
- distributed session management
Expected result:
- ChronoSeal raises cost and complexity
- ChronoSeal does not claim complete prevention
- additional application-level controls are required
Attack Vectors and Mitigations
Replay
Attack: resend a previously accepted heartbeat.
Mitigations:
- stored
last_hashmust match requestprev_hash - accepted heartbeats rotate salt
- mutation step advances after acceptance
- timestamp drift is bounded
Signature Forgery
Attack: submit a heartbeat without the browser session private key.
Mitigations:
- Ed25519 signature over canonical payload
- public key registered during
/init - signature verified on every heartbeat
- signature covers mutation step and gene commitment
Hash-Chain Desynchronization
Attack: submit a heartbeat from stale client state.
Mitigations:
- server compares request
prev_hashto storedlast_hash - server computes the next hash only after all validation passes
- rejected heartbeats do not advance server state
Mutation Tampering
Attack: forge or skip synthetic gene mutations.
Mitigations:
- server stores the pending mutation program
- request must include the expected
mutation_step - server applies the mutation independently
- commitment includes candidate gene state,
session_id, and step - mismatch causes silent rejection
Session Identifier Theft
Attack: reuse a stolen session_id.
Mitigations:
session_idalone is insufficient- attacker also needs current private key, hash state, salt, mutation step, and mutation state
- stale attempts fail after the real session advances
Failure Oracle Probing
Attack: send malformed requests and inspect responses to infer validation rules.
Mitigations:
- heartbeat semantic failures return
200 OKwith{"status":"ok"} - accepted heartbeats are distinguished only by next-state fields
- detailed validation errors are not returned to the client
Storage Tampering
Attack: alter persisted session state.
Mitigations:
- run the daemon under a dedicated user
- restrict SQLite database permissions
- protect Valkey behind trusted network boundaries
- use normal host hardening and backups where persistence matters
Storage is trusted. If an attacker can modify storage, they can affect session continuity.
Behavioral Checks
ChronoSeal validates:
- minimum event count
- minimum movement distance
- maximum average speed
- pause count
- timestamp drift
- basic fingerprint field ranges
These checks are cost signals. They are not proof of humanity and should not be the only security layer for high-risk actions.
Privacy Constraints
ChronoSeal intentionally avoids:
- persistent user identifiers
- browser history collection
- device fingerprint databases
- cross-session identity graphs
- long-term behavioral profiles
Session data is short-lived by default. Persistent storage is operator-selected through sqlite-in-disk or valkey.
Limitations
ChronoSeal does not protect against:
- real users intentionally automating or abusing access
- complete browser farms with realistic input
- compromised server hosts
- tampered storage
- server-side application vulnerabilities
- credential theft outside ChronoSeal
- policy decisions that require identity, risk scoring, or business context
Operational Security
Recommended:
- serve all traffic over HTTPS
- keep
/initand/hbsame-origin with protected content when possible - run behind a reverse proxy
- keep debug logs disabled in production
- protect storage and log directories
- monitor health and metrics
- use
sqlite-in-memoryfor ephemeral sessions - use
sqlite-in-diskorvalkeyonly when persistence is required
Disclosure
See ../SECURITY.md for the vulnerability disclosure policy.