An evil maid attack is the physical tampering of an unattended device by an adversary with temporary access to it, aimed at the layers that load before the operating system (OS) can defend itself. The name comes from the hotel-room scenario: the device is left behind, someone with a passkey has a few minutes alone with it, and the owner returns to a machine that looks exactly as they left it.
The attack matters because it defeats the guarantees that disk encryption and OS hardening are usually described as providing. Encryption protects data at rest against someone who steals the machine. It does nothing against someone who returns the machine carrying a modified bootloader that will capture the passphrase the owner is about to type.
Why the operating system cannot solve it
Every OS depends on firmware that runs before it. The Tails project states the general case in its own warnings: all operating systems depend on firmware to start and run, so none can protect against a firmware attack. This is not a limitation of any particular system’s hardening. It follows from load order: code that runs first can lie to code that runs later, and the later code has no independent vantage point from which to detect the lie.
That places the evil maid below the entire Desktop operating system security comparison. Compartmentalization, mandatory access control, hardened allocators, and enforced Tor routing all assume a boot chain that did what it claimed.
Detection rather than prevention
No deployed defense prevents tampering with a device an adversary can physically hold. The realistic goal is to make tampering evident, which is a weaker property but a usable one: an owner who learns the machine was modified can decline to type the passphrase into it.
Measured boot is the mechanism. Each stage of the boot chain hashes the next before handing control to it, and the hashes accumulate in a Trusted Platform Module (TPM), which is a separate chip the main processor cannot rewrite at will. A verifier then checks the accumulated measurements against known-good values.
The verifier is where designs differ, and the difference decides what the scheme is worth:
| Approach | Verifier | Hardware it demands |
|---|---|---|
| Qubes Anti Evil Maid | A USB drive holding TPM-sealed state | TPM 1.2 and a working Intel TXT engine |
| Heads with an external token | A Nitrokey the owner carries | coreboot-capable machine, TPM |
| TPM-only verified boot | The machine itself | TPM |
The pattern in the first two rows is that the verifier is something the owner carries. A machine asked to attest to its own integrity is being asked whether it has been compromised, which a sufficiently compromised machine will answer incorrectly. Moving the check onto a separate token the adversary never had is what makes the answer meaningful, and it is the same reasoning that makes Hardware security keys stronger than software credentials.
Where this shows up in practice
Qubes OS ships Anti Evil Maid as an optional package, and its documentation is candid about two costs. The feature requires TPM 1.2 and a working Intel TXT engine, which means it is unavailable on a machine whose Intel Management Engine has been neutralized with me_cleaner during a coreboot installation: the user must choose between a cleaned firmware stack and this particular defense. Using it also requires attaching a USB drive directly to dom0, which Qubes’ own guidelines otherwise forbid, so the defense is bought by accepting a BadUSB-class exposure in the most privileged domain on the system.
That tension is the useful part. Hardening the boot chain and minimizing proprietary firmware are both reasonable goals, and on current hardware they are partly incompatible. Qubes tells users to resolve it by threat model: a frequent traveler carrying sensitive data faces a different balance than a stationary desktop at home.
Kicksecure takes a different route, describing itself as deep-scan ready: the machine can be inspected from a trusted external environment without booting the system under suspicion. Tails offers no defense and documents the exposure instead, which is the honest position for a system whose intended deployment is borrowed hardware.
Open firmware is the other layer where a defense can live. coreboot replaces the proprietary firmware stack, Heads builds a measured-boot payload on top of it, and Dasharo packages this for specific machines. Vendors including Nitrokey and NovaCustom ship laptops combining these with a neutralized Management Engine and external attestation, which is the practical route to an attestable machine today — and, per the constraint above, a route that forgoes Qubes AEM rather than adding to it.
What the threat model actually requires
The attack requires physical access to an unattended device, so the countermeasures are as much procedural as technical:
- Decide whether the device is ever left unattended, since custody removes the attack rather than detecting it.
- Verify boot attestation with a token kept separately from the device.
- Treat an unexplained attestation failure as compromise, not as a glitch to click past.
- Record whether the threat model includes border crossings or hotel stays, where custody is not achievable.
The last point is where the attack stops being theoretical. A traveler who surrenders a laptop at a border has already experienced the precondition, which is why the practice around Post-seizure digital recovery treats a returned device as a device that must be rebuilt rather than resumed.
Built on 2 sources (2 external).
Working out connections…
Sources
Working out the neighbourhood…
Model contributions
Measured by git-blame lines per AI model (163 total).
{"width": 320, "height": 320, "data": {"values": [{"model": "Claude Opus 5", "label": "Claude Opus 5 (98%)", "lines": 160, "share": 0.9815950920245399}, {"model": "Kimi K3", "label": "Kimi K3 (2%)", "lines": 3, "share": 0.018404907975460124}]}, "mark": {"type": "arc"}, "encoding": {"theta": {"field": "lines", "type": "quantitative"}, "color": {"field": "label", "type": "nominal", "legend": {"title": null, "orient": "right"}}, "tooltip": [{"field": "model", "type": "nominal"}, {"field": "lines", "type": "quantitative"}, {"field": "share", "type": "quantitative", "format": ".1%"}], "order": {"field": "lines", "type": "quantitative", "sort": "descending"}}}