Skip to the content
nullroute
Browse the docs

Partially in scope: mitigated, but do not rely on it

Coercion

Not built yet. Indistinguishable profiles and a wipe PIN are planned for phase 7 and no part of either exists in the code today. What the device has right now is a passphrase and a failed-attempt counter that erases the sealed blob, and that counter is not a coercion defence: anyone holding the card can copy it first and guess against the copy forever.

This section describes the intended design so the limits are on record before anything is built, not after.

It will not protect you from someone who is willing to hurt you. The source code of this project is public. Anyone who reads it will know that multiple profiles are possible, that an apparently empty device may be hiding one, and that a wipe PIN exists. An adversary who has done ten minutes of research will simply keep applying pressure.

What it actually buys you is time and plausibility against an unsophisticated adversary, for example a thief who wants a quick win and moves on. That is a real but narrow benefit.

The device says this in the UI, not just in this document. Nothing in the running system uses the word "duress", because a screen that says "duress PIN" tells the adversary what to ask for.

If you are under credible physical threat, give them the money.

Device substitution and evil maid

Not built. An anti-phishing phrase shown at unlock, derived from the seed and the passphrase so that a swapped or reflashed device shows different words, is planned and does not exist. The device name and colour are not a substitute: they are a plain file on the card that anyone holding it can edit, and nothing authenticates them.

When it is built, it will work only if you read the words every time, and only if you noticed and memorised them in the first place. It is a detection aid with a human in the loop, which means it fails the way humans fail. There is no secure boot chain in the current design (it is a phase 7 stretch goal), so a sufficiently prepared attacker who has had the device unattended can replace the software.

An unlocked device that has been left

The wallet closes itself after ten minutes with nobody touching the screen, and the seed is zeroized when it does. Before that existed, a device unlocked to check one address stayed unlocked until somebody remembered to lock it or pulled the power, and the screen that displays a mnemonic for backup was one of the places it could be left.

What this defends against is the device being left, and nothing else. It is worth nothing against somebody standing at the device, who touches the screen and keeps it open. It is worth nothing against an attacker who takes an unlocked device and reads its memory in the next few seconds. And it does nothing about the window itself: for up to ten minutes after you walk away, the seed is in memory on a device you are not looking at.

It is not configurable. A setting that turns a lock off is a setting worth attacking, and one stored where it can be read before a passphrase is one an attacker with brief access to the card could turn off and hand back.

The countdown appears a minute before the deadline, and any touch clears it. The warning exists because a lock that arrives with no warning is indistinguishable from a crash, and a security feature that interrupts somebody mid-review is one they will find a way around.

Malicious QR or SD payloads

Parsers are fuzzed, size-limited, and fail closed. This is real hardening and it raises the bar considerably.

It used to credit removable media being mounted noexec,nosuid,nodev as well. Nothing in this repository mounts removable media: there is no automount, no udev rule that mounts removable media and no mount unit, the daemon contains no mount call and is forbidden the syscall group, and the only filesystems carrying those options are the /tmp, /var/tmp and /run tmpfs mounts, which are not where a payload arrives. Claiming a control the tree does not implement is the failure this document exists to avoid, so it is struck rather than softened.

It is not a proof. These are hand-written parsers in a memory-safe language processing attacker-controlled input, and the honest claim is "defensively written and fuzzed", not "cannot be exploited".


Rendered from docs/THREAT-MODEL.md, the same bytes that ship with the code. SHA-256 d932f13db7fe836f45194ab98069c47dc556d4f29b2cfbf0ef1ab3bf7b334ffd