# Xiaozhi ESP32 server: an OTA call hands out another device's token

> A device token in Xiaozhi-esp32-server-java proves only which MAC address asked for it, and the OTA route gives one to anyone.

- **Severity:** Medium: Real and reproducible, but needs unusual setup, user help or a narrow audience. Plan a fix.
- **Category:** Vulnerability
- **Published by:** VulnCheck
- **Disclosed:** 2026-10-15
- **CVE:** CVE-2026-111623
- **CVSS:** 6.3
- **Affects:** Xiaozhi-esp32-server-java
- **Research by:** [hieuPenguinnn](https://github.com/hieuPenguinnn)
- **Primary source:** https://www.vulncheck.com/advisories/xiaozhi-esp32-server-java-through-6.1.0-authentication-bypass-via-ota-endpoint-token-issuance
- **Page:** https://theinjection.dev/items/xiaozhi-esp32-java-ota-token-issuance/

CVE-2026-111623 lets an anonymous caller post a victim's MAC address to /api/device/ota in Xiaozhi-esp32-server-java and receive a working WebSocket token for that device. The token exposes the device's system prompt and provider credits.

## What happened

VulnCheck published CVE-2026-111623 for Xiaozhi-esp32-server-java on October 16, 2026 with a public date of October 15, crediting the finder hieuPenguinnn, and rates it 6.3 under CVSS 4.0. The write-up is a source review of release tag v6.1.0 and says runtime validation was not performed. No fix is recorded, and the project's GitHub security advisory count was zero when the finder looked.

## How it works

Four weaknesses line up. The OTA route carries the @SaIgnore annotation, so it needs no login. For a device already bound to a user, the handler returns a device token without checking that the caller is that device or that owner. The token is an HMAC over the normalized device id and a timestamp, with nothing tied to a user or a session, and it stays valid for 30 days by default. The WebSocket handshake then accepts any valid token for that MAC and binds the connection to the device and its owner.

## Who is affected

Versions through 6.1.0 are listed, but only where the operator set xiaozhi.device-auth.secret; the write-up excludes the default configuration that leaves the secret unset. An attacker needs the victim device's MAC address and network reach to the OTA endpoint and the dialogue service. Hobby and small-office deployments that exposed those ports to the internet are the realistic case.

## What to do

Keep the OTA endpoint and the dialogue service port off the public internet, and treat any LLM, speech-to-text or text-to-speech key configured on an exposed instance as abused until the bills say otherwise. The write-up's fix is to stop returning a reusable channel token to anonymous OTA callers for bound devices, issue short-lived single-use activation tokens instead, and bind tokens to a per-device secret provisioned at setup rather than to the MAC address.

## Quick facts

- **CVE:** CVE-2026-111623, assigned by VulnCheck
- **CVSS:** 6.3 under CVSS 4.0 and 5.6 under CVSS 3.1, both from VulnCheck
- **Affected:** Xiaozhi-esp32-server-java through 6.1.0, only when xiaozhi.device-auth.secret is set
- **Fixed in:** No patched version recorded
- **Attack type:** Authentication bypass by spoofing, CWE-290
- **Token lifetime:** 30 days by default, from the expireSeconds setting of 2,592,000 seconds
- **What it reaches:** The role's private system prompt, the conversation history, and the device's LLM, STT and TTS credits
- **Not established:** Code execution, and reading raw stored provider secrets back
- **Found by:** hieuPenguinnn, from source review, with no runtime testing

## Sources

1. [VulnCheck Advisory](https://www.vulncheck.com/advisories/xiaozhi-esp32-server-java-through-6.1.0-authentication-bypass-via-ota-endpoint-token-issuance)
2. [Researcher Write-Up](https://hackmd.io/@hieuPenguinnn/xiaozhi-esp32-server-java-ota-device-token-issuance)
3. [CVE Record](https://cveawg.mitre.org/api/cve/CVE-2026-111623)
4. [GitHub Advisory](https://github.com/advisories/GHSA-g79m-4gpq-p8x3)
5. [Token Source](https://github.com/joey-zhou/xiaozhi-esp32-server-java/blob/v6.1.0/xiaozhi-common/src/main/java/com/xiaozhi/communication/auth/DeviceAuthService.java#L76-L81)
