Summary
TinyGS enables ArduinoOTA without calling ArduinoOTA.setPassword(...). On the local network, an attacker who can reach the device’s ArduinoOTA service may upload firmware without an OTA password, leading to full device compromise (equivalent to remote code execution on the ESP).
Severity (suggested): High
CWE: CWE-306 (Missing Authentication for Critical Function)
Details
In tinyGS/src/ArduinoOTA/ArduinoOTA.cpp, arduino_ota_setup() configures hostname and starts OTA, but never sets a password:
ArduinoOTA.setHostname ("TinyGS");
ArduinoOTA.begin ();
(Approx. lines 55–57.)
ArduinoOTA authentication is only enforced when setPassword / setPasswordHash is used before begin(). Without it, OTA updates are effectively unauthenticated on the reachable network interface.
PoC
White-box confirmation: the call sequence is setHostname → begin with no setPassword in this file.
Dynamic verification (authorized lab device only): from a machine on the same LAN as a running TinyGS node, use a standard ArduinoOTA / espota-style update against the device hostname/IP; observe that no OTA password is required.
I can provide additional screenshots/source citations if helpful. Please do not treat this as authorization to test third-party devices.
Impact
- Unauthenticated firmware replacement on vulnerable TinyGS devices reachable on the network
- Persistent compromise of the tracker (code execution, config theft, malicious TX behavior)
Who is impacted: Operators running TinyGS firmware builds that call arduino_ota_setup() without an OTA password, especially on open/flat LANs or exposed Wi-Fi.
Remediation
- Call
ArduinoOTA.setPassword(...) (or hash variant) before ArduinoOTA.begin(), using a per-device secret.
- Prefer disabling ArduinoOTA in production builds, or gate it behind an explicit compile-time/config flag.
- Document that OTA must not be left open on untrusted networks.
Happy to coordinate on fix and disclosure. Please credit me if you publish an advisory or request a CVE.
Summary
TinyGS enables ArduinoOTA without calling
ArduinoOTA.setPassword(...). On the local network, an attacker who can reach the device’s ArduinoOTA service may upload firmware without an OTA password, leading to full device compromise (equivalent to remote code execution on the ESP).Severity (suggested): High
CWE: CWE-306 (Missing Authentication for Critical Function)
Details
In
tinyGS/src/ArduinoOTA/ArduinoOTA.cpp,arduino_ota_setup()configures hostname and starts OTA, but never sets a password:ArduinoOTA.setHostname ("TinyGS"); ArduinoOTA.begin ();(Approx. lines 55–57.)
ArduinoOTA authentication is only enforced when
setPassword/setPasswordHashis used beforebegin(). Without it, OTA updates are effectively unauthenticated on the reachable network interface.PoC
White-box confirmation: the call sequence is
setHostname→beginwith nosetPasswordin this file.Dynamic verification (authorized lab device only): from a machine on the same LAN as a running TinyGS node, use a standard ArduinoOTA / espota-style update against the device hostname/IP; observe that no OTA password is required.
I can provide additional screenshots/source citations if helpful. Please do not treat this as authorization to test third-party devices.
Impact
Who is impacted: Operators running TinyGS firmware builds that call
arduino_ota_setup()without an OTA password, especially on open/flat LANs or exposed Wi-Fi.Remediation
ArduinoOTA.setPassword(...)(or hash variant) beforeArduinoOTA.begin(), using a per-device secret.Happy to coordinate on fix and disclosure. Please credit me if you publish an advisory or request a CVE.