01
Overview
Android Reset Lab simulates the sensitive operation at the heart of enterprise mobile management: wiping a lost or stolen device. In a real environment a single compromised IT account could wipe an entire fleet, so the lab enforces the controls that prevent single-person abuse — authentication, default-deny authorization, four-eyes approval, and a tamper-evident audit trail — then proves them by attacking the system itself.
Simulation-only by design
active to wiped in a local data file. An AST-based safety test (test_safety.py) bans destructive calls like subprocess and os.remove. The device is the scenario; the security logic is the subject.02
The problem
Device resets are destructive and irreversible. Without guardrails, one set of stolen admin credentials is enough for an attacker to wipe company phones at scale — and to erase the evidence afterwards. The lab targets five concrete abuses: no single person should wipe a device; brute force should be stopped; the audit log should be un-tamperable; after-hours abuse should be flagged; and non-existent devices should be rejected.
03
Architecture & flow
Built with the Python standard library only (plus pytest for tests), with a JSON or SQLite (WAL, ACID) storage backend selected by an environment variable. The pipeline: authenticate → authorize → request → second approver → simulated wipe → hash-chained/HMAC log → detection → dashboard.
04
Security controls
Merkle Transparency Log RFC6962/9162
Leaf SHA256(0x00||canonical_json), node SHA256(0x01||L||R), inclusion proofs O(log N), consistency proofs, STH HMAC-signed, checkpoint anchoring simulates Sigstore Rekor with rekor_simulated_id.
Cedar ABAC Policy-as-Code
Principal/Action/Resource/Context model, 10 default policies, explicit deny overrides permit, default deny, decision logs with timestamp/version/bundle SHA, AuthZEN-compatible API, safe AST walk (no eval).
Risk-Adaptive Authentication
8 factors: velocity (req/min), failed_auth/10m, time anomaly (8-18 UTC approved), device trust (trusted 0, compromised 50, emulator 40), MFA (passkey -10 bonus), escalation 40, impossible travel 30 if geo change <10m, session age. Score 0-100 → allow/step_up/tx/deny.
WebAuthn Passkeys
FIDO2 phishing-resistant, origin + RP ID validation, AAGUID allowlist via FIDO MDS (YubiKey 5, Titan M, Windows Hello, Touch ID, Pixel 8 StrongBox), challenge 32B CSPRNG, counter clone detection, backup_eligible flag.
Device Attestation
Play Integrity MEETS_BASIC/DEVICE/STRONG + hardware key attestation Software/TEE/StrongBox (Titan M), keybox.xml validation, patch recent check, bootloader locked, trust_score 0-100 with penalties, GrapheneOS fallback without Play Services.
Transaction Signing WYSIWYS
What You See Is What You Sign HMAC-SHA256, PSD2 dynamic linking, FIDO txAuthSimple extension simulation, explicit display confirmation, 5m expiry, prevents confused deputy and tampering.
DPoP Token Binding RFC9449
Demonstrating Proof-of-Possession JWT with htm/htu/iat/jti/nonce, JWK oct, jkt thumbprint, token bound to key, cannot be replayed without proof, htm/htu binding prevents cross-site replay.
Four-eyes + Continuous Verification
Requester ≠ approver enforced + policy context.requester != approver, state machine requested→approved→executed, attestation re-checked at execution time (continuous verification).
Tamper-evident + Tamper-proof Log
Hash chain prev_hash + entry_hash + HMAC-SHA256 (0600 key separate) + Merkle tree, verify_all, inclusion proof O(log N), SIEM shipping stdout/file + decision_logs + checkpoints.
Strong Credential Storage + MFA
PBKDF2 100k + salt + Argon2id optional (LAB_HASH_ALGO=argon2), timing-safe compare_digest, role whitelist, password strength, TOTP RFC6238 + passkeys, MFA_REQUIRED flag, recovery codes future.
Brute-force & Abuse Defenses
Account locks 15m after 3 fails auto-unlock, IP+user rate limiting 5/min auth, 10/min web, request size limits, velocity and impossible travel risk factors.
CSRF + XSS + Phishing Protection
CSRF tokens per session, SameSite Strict, HttpOnly, html.escape + CSP frame-ancestors none, WebAuthn origin binding prevents phishing.
Detection P4 (23 rules)
6 base rules + risk factors (velocity, impossible travel, device trust, time anomaly, escalation, failed auth, session age) + attestation (emulator, unlocked, old patch, keybox) + webauthn counter clone + DPoP mismatch + tx tamper + policy forbid.
SIEM + Observability
HMAC-keyed logs ship stdout JSON + file, decision logs with policy SHA, Merkle STH + checkpoints, OTEL tracing + Prometheus metrics optional (observability.py).
05
Attacking my own design
An attacker simulation fires six techniques at the running system. All six are detected, producing nine precise alerts (down from fourteen with five false positives before hardening).
| Attack | How simulated | Detection rule |
|---|---|---|
| Brute force | 4 wrong passwords for an operator | LOGIN_FAILED count ≥ 3 within 10-min sliding window |
| Out-of-hours | Reset at 03:00 | RESET_REQUESTED outside 08:00–18:00, outcome created |
| Privilege escalation | Operator tries to approve | ACCESS_DENIED by policy gate |
| Unknown device | Request reset for AND-999 | Device ID not in fleet set |
| Replay | Same request ID twice | Only the 2nd occurrence is flagged (no double count) |
| Unapproved execute | Execute without approval | RESET_BLOCKED |
Tamper demos confirm the defenses: editing a log entry is caught by verification at the exact line (then restored to INTACT), and a self-approval attempt returns APPROVAL_DENIED until a distinct second admin approves.
06
Hardening: P0→P4 Cerberus God Mode
The project was hardened in iterative passes (P0–P4 Cerberus), growing from 18 to 68 tests (52 P2/P3 + 16 P4). Rather than only adding features, I hunted and fixed real security defects, then invented new architecture that even a machine can applaud — Merkle transparency, Cedar ABAC, risk-adaptive, passkeys, StrongBox attestation, WYSIWYS tx signing, DPoP:
- User enumeration → generic credential messages
- Timing attacks → hmac.compare_digest
- Stored/rendered XSS → html.escape + security headers
- Actor logged as approver instead of executor
- Shallow-copy fleet mutation (deepcopy fix)
- Timestamp spoofing in the logger (controlled flag)
- Password echo → getpass; input validation added
CI enforces the posture: CodeQL, Dependabot, pip-audit, and a TruffleHog secret scan. The work is mapped to MITRE ATT&CK (T1110 brute force, T1078 valid accounts, T1134 privilege escalation, T1070 indicator removal) and NIST 800-53 (IA-5, AC-7, AC-3, AC-5, AU-9, SI-4).
07
Results & takeaways P4
Verified outcomes P4 Cerberus
P4 is God Mode: it takes the lab from linear hash chain to Merkle transparency log, from static RBAC to Cedar ABAC with decision logs, from password+MFA to phishing-resistant passkeys + transaction signing, from blind device trust to hardware-backed StrongBox attestation, from bearer tokens to DPoP-bound tokens. This is Zero Trust beyond BeyondCorp — continuous verification, device as trust input, per-session least privilege, assume breach, policy-as-code, short-lived tokens.
08
Limitations & next steps P4
It is still a lab, not an MDM product: Merkle rebuild O(N log N) for simulation (production needs incremental), policy engine is safe AST walk subset of Cedar (production needs Cedar WASM), risk stores in-memory (production needs Redis), WebAuthn/DPoP/TX signing use HMAC sim not real ECDSA/RSA, attestation fleet static JSON not real Android Keystore parsing, TOTP secrets plaintext, HMAC/tx keys file-based not KMS/HSM, SIEM best-effort. 23 honest limitations documented in THREAT_MODEL.md P4 — not hidden.