| name | apply-iot-device-hardening |
| description | Use when preparing IoT devices for production deployment — removing default credentials, disabling debug interfaces, encrypting stored data, and implementing physical tamper detection. |
| source | OWASP IoT Top 10 I9 I10 (owasp.org/www-project-internet-of-things/); ETSI EN 303 645; NIST SP 800-193; UK PSTI Act (2024 Product Security and Telecommunications Infrastructure Act) |
| tags | ["security","owasp","iot","device-hardening","credentials","tamper-detection","embedded","hardware"] |
Apply IoT Device Hardening
Remove default credentials, disable JTAG/UART debug interfaces, encrypt data at rest, and implement physical tamper detection — preventing both remote and physical compromise of deployed IoT devices.
Why This Is Best Practice
Adopted by: OWASP IoT Top 10 I9 (Insecure Default Settings) and I10 (Lack of Physical Hardening). ETSI EN 303 645 Section 5.1 mandates unique per-device credentials and prohibits default passwords. The UK Product Security and Telecommunications Infrastructure (PSTI) Act 2024 bans universal default passwords for consumer IoT — manufacturers face fines up to £10M. NIST SP 800-193 requires firmware resilience against physical access. Medical IoT (FDA guidance 2023), industrial IoT (IEC 62443), and automotive IoT (UNECE WP.29) all mandate these controls.
Impact: Mirai botnet's primary infection vector was default credentials (admin/admin, root/1234) on Telnet and HTTP — 600,000 devices compromised within weeks of release. Shodan 2023 found 2.3 million IoT devices still using factory default credentials. Physical hardware attacks allow credential extraction from unprotected UART/JTAG interfaces in under 5 minutes with a $30 FTDI adapter and publicly available firmware extraction tools. NIST estimates 30% of IoT breaches involve physical access to the device.
Why best: Remote hardening (network services, TLS) protects against internet-facing attacks; physical hardening adds a layer against supply chain attacks, insider threats, and theft of deployed devices. Default credentials are unique in that they're publicly known to attackers before the device is even deployed — per-device unique credentials eliminate this entire attack class at zero ongoing cost.
Sources: OWASP IoT Top 10 I9, I10; ETSI EN 303 645 sections 5.1 and 5.2; UK PSTI Act 2024; FDA "Cybersecurity in Medical Devices" guidance (2023)
Steps
-
Generate unique per-device credentials at manufacturing time:
import secrets
import hashlib
def provision_device(device_serial: str, device_mac: str) -> dict:
admin_password = secrets.token_urlsafe(16)
private_key = generate_ec_key()
cert = sign_device_certificate(
private_key=private_key,
subject=f"CN={device_serial},O=Company,C=US",
ca_key=MANUFACTURING_CA_KEY
)
device_config = {
"admin_password_hash": bcrypt.hash(admin_password),
"device_cert": cert,
"device_key": private_key,
"serial": device_serial,
}
return device_config
-
Disable JTAG and UART debug interfaces in production:
void disable_debug_interfaces(void) {
FLASH_OBProgramInitTypeDef ob_init = {0};
HAL_FLASHEx_OBGetConfig(&ob_init);
ob_init.OptionType = OPTIONBYTE_USER;
ob_init.USERType = OB_USER_TZEN;
ob_init.USERConfig = OB_TZEN_ENABLE;
ob_init.OptionType |= OPTIONBYTE_RDP;
ob_init.RDPLevel = OB_RDP_LEVEL_2;
HAL_FLASH_Unlock();
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_OBProgram(&ob_init);
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
}
Rules
- RDP Level 2 on STM32 (and equivalent on other MCUs) is permanent and irreversible — verify the production firmware is correct before enabling it.
- Per-device credentials must be generated with a CSPRNG — never derived from predictable values (MAC address, serial number, hash of serial number).
- Tamper detection response must clear keys before reset — a tampered device that reboots normally with keys intact defeats the tamper protection.
- Debug access restrictions must be in the release build configuration, verified by the manufacturing test procedure.
Common Mistakes
- Same credential on all devices of the same model — a single device's credential extraction compromises all devices of that model; per-device credentials are mandatory.
- UART debug console left enabled in release build —
CONFIG_CONSOLE_UART=y in Kconfig; audit release build configs before tapeout/production flash.
- Storing credentials in plaintext flash — flash memory is readable with a logic analyzer or by desoldering; encrypt all stored credentials with a hardware-derived key.
- Tamper detection only in application, not bootloader — an attacker can replace the application; tamper detection must be in the first-stage bootloader or hardware-enforced.