Skip to content

Unauthenticated Firmware Upload in Official `HTTP_Server_AES_OTA_Update` Example Allows Remote Code Execution

High
lucasssvaz published GHSA-v7jh-c872-6jmp Mar 17, 2026

Package

ESP32 Arduino (Arduino)

Affected versions

3.3.7

Patched versions

1d12a05379517f4a3738f215b8e45bfb59bc04fa

Description

Summary:
The official example libraries/Update/examples/HTTP_Server_AES_OTA_Update/HTTP_Server_AES_OTA_Update.ino starts an ESP32 access point and exposes a firmware update endpoint at /update without authentication. An attacker who can join the device AP can access the update page and upload arbitrary firmware, which is then written to flash and executed after reboot, resulting in remote code execution (RCE).

This appears to be an omitted OTA example after the repository fixed related OTA update vulnerabilities in OTAWebUpdater.ino, WebUpdate.ino, and HTTPUpdateServer.h in commit f4fdecc60c465384e465a4b1d2bd1eac8f67912e (fix(csrf): Fix SCRF vulnerability in OTA examples and libraries (#11530)), but did not update HTTP_Server_AES_OTA_Update.ino.

Impacted Source File:

Vulnerability Details:

  • The example exposes the update page at /update and returns the upload form without any authentication checks:
    • GET handler: lines 122-124
  • The same endpoint accepts POST uploads and directly writes attacker-controlled bytes via Update.begin, Update.write, and Update.end:
    • POST handler registration: lines 127-178
    • Flash write start: lines 145-156
    • Flash write body: lines 164-168
    • Flash finalize and reboot: lines 169-175
  • The example enables AP mode by default with #define WIFI_MODE_AP, starts a captive DNS responder, and prints the update URL to the serial console:
    • AP startup: lines 189-195
    • Server startup and banner: lines 222-226

There is no authentication gate, CSRF protection, or equivalent trust boundary before the uploaded firmware is processed.

Attack Scenario:

  1. A device is flashed with the official HTTP_Server_AES_OTA_Update example.
  2. The device boots in AP mode and exposes an update page at http://192.168.4.1/update.
  3. An attacker within radio range joins the AP.
  4. The attacker requests /update and receives the firmware upload form without authentication.
  5. The attacker uploads a firmware image to the firmware field.
  6. The device writes the uploaded image to flash and reboots into attacker-controlled code.

Impact:

  • Unauthenticated firmware upload
  • Remote code execution on the ESP32 device
  • Full compromise of device integrity and behavior

Hardware Reproduction:
This issue was reproduced on real ESP32 hardware on March 10, 2026.

  1. The example was compiled and flashed to an ESP32.
  2. Serial output confirmed that the official example started an AP and enabled the update endpoint:
Booting Sketch...
Wifi AP started, IP address: 192.168.4.1
Upload Decryption Ready
HTTPUpdateServer ready with Captive DNS!
Open http://anyname.xyz/update in your browser
  1. From a separate client connected to the ESP32 AP, the update page was accessible without authentication:
curl -i http://192.168.4.1/update

Observed response:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 956
Connection: close

The response body contained the firmware upload form.

  1. A firmware image upload succeeded without authentication:
curl -F "firmware=@C:\HTTP_Server_AES_OTA_Update.ino.bin" http://192.168.4.1/update

Observed response:

<META http-equiv="refresh" content="15;URL=/">Update Success! Rebooting...

This demonstrates that the example allows unauthenticated OTA upload and execution of uploaded firmware.

Proof of Concept (PoC):
Check unauthenticated access to the update page:

curl -i http://192.168.4.1/update

Upload firmware without authentication:

curl -F "firmware=@HTTP_Server_AES_OTA_Update.ino.bin" http://192.168.4.1/update

Recommended Remediation:

  • Require authentication before serving or accepting any OTA upload in this example.
  • Add CSRF protection consistent with the July 2025 OTA fixes.
  • Avoid shipping official OTA examples that allow unauthenticated firmware writes by default.
  • Document that firmware update examples must not be exposed without authentication and request-origin validation.

Related Previously Accepted Issue:

  • CVE-2025-53540 / GHSA-9vfw-wx65-c872

References:

  • Previous accepted report: GHSA-9vfw-wx65-c872
  • Previous fix commit: f4fdecc60c465384e465a4b1d2bd1eac8f67912e

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Adjacent
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

CVE ID

No known CVE

Weaknesses

Missing Authentication for Critical Function

The product does not perform any authentication for functionality that requires a provable user identity or consumes a significant amount of resources. Learn more on MITRE.

Credits