CWE-1319, Improper Protection against Electromagnetic Fault Injection (EM-FI), describes a device that can be pushed off its normal behavior by a nearby magnetic pulse. The result is that internal information leaks or a security mechanism gets bypassed. It matters most to people who design or select microcontrollers, system-on-chip parts and secure elements, and to firmware authors who run on them.
How it happens
An EM-FI setup is a pulse generator driving a coil. The coil produces a short, local, transient magnetic field. That field induces current in the wires of the integrated circuit and disturbs signals, both internal and external, at the moment the attacker chooses.
MITRE lists what a well-timed fault can do:
- Bypass security mechanisms such as secure JTAG or Secure Boot.
- Leak device information.
- Modify program flow.
- Perturb secure hardware modules, for example random number generators.
The attacker needs physical proximity to the device. That is the key difference from most weaknesses on this site: the exploit is local and hands-on, but it can be repeated on every unit of the same model.
The record for this weakness includes CVE-2020-27211, a chain in which a microcontroller system-on-chip reads a register value stored in flash to set the product protection state on the memory bus, without protection against fault injection.
What an attacker gains
MITRE lists consequences across confidentiality, integrity, access control and availability: modify memory, read memory, gain privileges or assume identity, bypass a protection mechanism, and execute unauthorized code or commands.
How to find it
The record has no detection methods. In practice the question for a design review is simple: for each security decision (is secure boot on, is debug locked, did the signature check pass), what happens if the instruction that makes that decision is disturbed once? If one glitch can flip the outcome, the design is exposed.
How to fix it
MITRE's mitigations apply at architecture, design and implementation time:
- Redundancy. Replicate critical operations and compare the outputs to spot an injected fault.
- Error detection and correction codes, which can detect adversarial faults and correct some low-multiplicity ones.
- Fail by default coding. When checking conditions, cover every case and fail on the default branch. A default branch that accepts a value without checking is easy to reach by manipulating data.
- Random behavior, such as random delays before critical operations, so timing is not predictable.
- Program flow integrity protection, with run-time checks that detect control flow inconsistencies.
- Sensors that detect variations in voltage and current.
- Shields, which are physical barriers that protect the chip from manipulation.
Here is the fail by default idea in plain C. The vulnerable version accepts anything that is not the expected reject value.
/* Vulnerable pattern: any value other than DENY is accepted */
if (auth_state == DENY) {
return -1;
}
run_privileged_path();
/* Safer pattern: accept only the exact expected value, fail otherwise */
if (auth_state == ALLOW) {
run_privileged_path();
} else {
return -1;
}
Quick check
Does the attacker need network access to use EM-FI?
No. The attack works by placing a coil near the device and producing a local magnetic pulse, so it needs physical proximity.
Why does "fail by default" help against fault injection?
A default branch that handles the last valid value without checking it is easy to reach when data is disturbed. Failing by default means a disturbed value is rejected instead of accepted.