The ESP32 ROM bootloader is verbose. Reset cause, fuse state, partition table, application banner — all of it lands on UART before the user code even starts. BootIntel reads the ROM output and the ESP-IDF banner to identify the device and its security posture in seconds.
What BootIntel detects on ESP32
- Secure Boot status — visible in the ROM message and in
esp_image:output. Most consumer ESP32 devices ship with it disabled; we flag it so you know whether the firmware is replaceable. - Flash Encryption state — same source. Without it, a dumped flash gives an attacker plaintext NVS (Wi-Fi creds, MQTT tokens, OTA URLs).
- JTAG fuse state — eFuse summary in the boot output shows whether JTAG was burned-disabled at the factory. If not, debug-port access remains until someone burns the fuse.
- Partition table layout — OTA-A / OTA-B / NVS / spiffs / fat. Surfaces "factory" partition that can roll back to vendor firmware and any partitions named in obviously-insecure ways.
- ESP-IDF version — stamped into the application banner; we match it against the highest-fixed ESP-IDF advisory.
- Boot mode — POWERON_RESET vs DEEPSLEEP_RESET vs DOWNLOAD_BOOT. Devices that enter DOWNLOAD_BOOT on a GPIO are user-flashable from UART — a real exposure for shipping product.
What a real ESP32 boot log looks like
rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0030,len:1184
load:0x40078000,len:13260
load:0x40080400,len:3032
entry 0x400805e4
I (29) boot: ESP-IDF v4.4.3 2nd stage bootloader
I (29) boot: compile time 12:54:32
I (29) boot: chip revision: 1
I (32) boot_comm: chip revision: 1, min. bootloader chip revision: 0
I (40) boot.esp32: SPI Speed : 40MHz
I (44) boot.esp32: SPI Mode : DIO
I (49) boot.esp32: SPI Flash Size : 4MB
I (54) boot: Enabling RNG early entropy source...
I (59) boot: Partition Table:
I (63) boot: ## Label Usage Type ST Offset Length
I (70) boot: 0 nvs WiFi data 01 02 00009000 00006000
I (78) boot: 1 phy_init RF data 01 01 0000f000 00001000
I (85) boot: 2 factory factory app 00 00 00010000 00100000
I (93) boot: End of partition table
I (97) esp_image: segment 0: paddr=00010020 vaddr=3f400020 size=2c890h
I (1234) cpu_start: Pro cpu start user code
I (1240) cpu_start: Application information:
I (1247) cpu_start: Project name: my-smart-plug
I (1253) cpu_start: App version: v1.2.3-12-g8c4f9d2
I (1259) cpu_start: Compile time: Apr 5 2024 14:22:11
I (1265) cpu_start: ELF file SHA256: 4f3a8b...
I (1271) cpu_start: ESP-IDF: v4.4.3Example findings BootIntel surfaces
- Secure Boot disabled (CRITICAL on production) — no "Secure Boot v2 enabled" line in the bootloader output. Firmware can be replaced via UART flash mode with no signature check.
- Flash Encryption disabled (HIGH) — a flash dump from a desoldered chip yields plaintext app + NVS. If the device stores Wi-Fi credentials, MQTT tokens, or cloud API keys in NVS, they're recoverable.
- ESP-IDF v4.4.3 outdated (MEDIUM) — known advisories in the BLE stack, mbedtls integration, and HTTP client are fixed in 4.4.6+. Match exact subrelease to the ESP-IDF security advisory feed.
Related reading
- Finding UART Pins on an Unknown Board — ESP32 modules vary; this covers how to locate TX/RX/GND on bare-board ESP32s.
- Device Fingerprinter — paste an ESP32 boot log and we identify the chip family + ESP-IDF version without sign-in.