Skip to content

Raivieiraadriano92/e2ee v2 red team - #1267

Draft
raivieiraadriano92 wants to merge 13 commits into
raivieiraadriano92/thu-787-e2ee-v2from
raivieiraadriano92/e2ee-v2-red-team
Draft

Raivieiraadriano92/e2ee v2 red team#1267
raivieiraadriano92 wants to merge 13 commits into
raivieiraadriano92/thu-787-e2ee-v2from
raivieiraadriano92/e2ee-v2-red-team

Conversation

@raivieiraadriano92

Copy link
Copy Markdown
Collaborator

No description provided.

A revoked device's retained bearer is refused (401) on the challenge
endpoint for any X-Device-ID, so the post-rotation canary re-fetch that
would re-derive the signing key never happens (the C5 residual). The
challenge device id is caller-asserted, gated only by device state, and
grants nothing given the account-wide signing key. Adds encryptionApiRequest
as the reusable A4 raw-request primitive.
A malicious server substitutes its own P-256 key on GET /encryption/org-key;
the client wraps the AK to it with no pinning, TOFU, or fingerprint check. The
offline tool with the attacker private key recovers row plaintext, the legit
operator key is locked out, and persistOrgEnvelope stamps its own fingerprint
over the attacker-wrapped blob — false assurance. C11's required pinning is
unmet.
Cross-row ciphertext swap fails GCM and codec.decode returns the raw wire
value, so the moved plaintext never renders — C3 relocation holds. Same-cell
rollback to an older ciphertext is AAD-valid (the AAD carries no version or
timestamp) and the client renders stale plaintext undetected — the residual
C3 flags, now witnessed end to end. Adds an editTask helper.
codec.encode has no v1 (no-AAD) writer — it always emits __enc:v2:<key_id>
with AAD — so no server input produces an AAD-free write. A hostile
scheme_version:1 on the metadata response cannot re-trigger migration on a
set-up device: ensureV2Encryption short-circuits already-v2 when a local AK
exists, before the scheme_version===1 branch. Adds forceSchemeVersion.
The thunderbolt-keys-sync BroadcastChannel is control-only — KeysSyncMessage
has no slot for key material and every handler just drops caches to re-read
authoritative IndexedDB. A forged same-origin barrage (reset, forged
key-staged, key-request for an attacker key_id) injects nothing and cannot
force plaintext: encodeWithoutKeys fails closed while a persisted AK exists.
An unknown key_id resolves request -> stage -> still-missing -> raw, never
plaintext.
recoverWithKey derives the recovery keypair from seed + server kdf_salt, then
checks the derived public halves against the stored recovery_* keys before any
unwrap or registration. A server that lies about kdf_salt yields a non-matching
public key and a clean Invalid recovery key — no access, no leak. Adds the
generic overrideEncryptionMetadata primitive.
On a phrase-keeping AK rotation (a routine device revoke), the client wraps
the new AK to the recovery_* public keys the server serves, unverified, and
/encryption/rotate stores whatever recovery keys the client submits. A
malicious server swaps in an attacker recovery keypair during the silent
re-anchor, then recovers the account on a fresh device and reads the victim's
plaintext. Falsifies C9's 're-anchoring cannot be abused for takeover'. Adds
the getKdfSalt reader.
Reads the thunderbolt-keys IndexedDB the app writes and asserts the AK and
device ECDH private key are non-extractable CryptoKeys (exportKey rejects),
and the ML-KEM secret is stored as an encrypted { iv, ciphertext } envelope,
never raw plaintext. A same-origin script or device-image thief can use these
keys but cannot lift their bytes.
@raivieiraadriano92 raivieiraadriano92 self-assigned this Sep 5, 2026
@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

Semgrep Security Scan

No security issues found.

@github-actions

github-actions Bot commented Sep 5, 2026

Copy link
Copy Markdown

PR Metrics

Metric Value
Lines changed (prod code) +2841 / -22
JS bundle size (gzipped) 🟢 640.3 KB → 631.8 KB (-8.5 KB, -1.3%)
Test coverage 🟢 81.68% → 81.92% (+0.2%)
Performance (preview) Preview not ready — Render deploy may have timed out
Accessibility
Best Practices
SEO

Updated Sat, 05 Sep 2026 18:26:30 GMT · run #2959

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant