A garbled name tag on a walkie-talkie that jams your phone's contact list
Meshtastic is an open-source LoRa mesh networking firmware used primarily by hobbyists, ham radio operators, and off-grid enthusiasts. In firmware versions prior to 2.7.23.b246bcd, a node broadcasting a User.long_name with malformed character encoding — either intentionally or via naturally occurring buffer truncation — poisons the node database that the Meshtastic iOS app synchronizes over BLE. The result: the iOS app enters a Bluetooth sync loop and the user loses control of their radio until the poisoned entry ages out of the mesh.
The vendor CVSS of 7.5 (AV:N/AC:L/PR:N/UI:N/C:N/I:N/A:H) technically fits the mechanics — network-adjacent, no auth, availability-only — but the *deployment reality* is nowhere near HIGH. This isn't running on domain controllers, hypervisors, or production infrastructure. It's running on $30 LoRa boards paired to hobbyist iPhones. The blast radius is 'my mesh radio app is stuck' — not fleet compromise, not data loss, not lateral movement. Vendor math is defensible; enterprise relevance is essentially nil unless you actually deploy Meshtastic operationally.
4 steps from start to impact.
Attacker joins the LoRa mesh
- RF proximity to target mesh
- LoRa hardware
- channel PSK if encrypted
- RF range is physical, not internet-scale
- most enterprise environments have zero Meshtastic footprint
- channel encryption blocks casual joiners
Broadcast a malformed User.long_name
User.long_name to a byte sequence with invalid UTF-8 / truncated multibyte characters and lets the mesh gossip protocol propagate the NodeInfo. Tooling: modified meshtastic-python CLI or direct protobuf crafting.- ability to transmit NodeInfo frames on the mesh
- same malformed payload can occur *naturally* from buffer truncation — so this is barely 'exploitation'
- no privilege escalation, no code exec
iOS app ingests poisoned NodeInfo over BLE
- victim runs Meshtastic iOS app
- victim's node is in mesh reception range of the poisoned NodeInfo
- Android users unaffected
- desktop / Python CLI users unaffected
Victim loses BLE control of their radio
- no alternate management path readily available
- radio itself keeps functioning for message pass-through
- Python CLI recovery is trivial for anyone technical
org.meshtastic.meshtastic iOS bundle and any managed Meshtastic firmware images. If zero installs, close the ticket. No mitigation SLA applies at LOW — this is a discovery task, not a deadline.meshtastic-python CLI are unaffected; using them avoids the iOS BLE sync loop entirely while firmware rolls out.- Perimeter firewalls / NGFW — the vulnerability path is LoRa RF, not IP; your edge cannot see or block it.
- EDR / MDM policy blocks on the iOS app — an unpatched app talking to an unpatched radio still triggers the loop; only the firmware fix or app update resolves it.
- Network IDS signatures — no IP traffic to inspect.
The supporting signals.
| CVE | CVE-2026-42566 |
|---|---|
| CWE | CWE-20 Improper Input Validation |
| Vendor CVSS | 7.5 HIGH — CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H (availability-only) |
| KEV | Not listed |
| EPSS | Not yet scored (disclosed 2026-07-20); expected <0.1% given niche footprint |
| Exploit PoC | No public weaponized PoC. Malformed payload can occur *naturally* via buffer truncation — trivial to reproduce |
| Affected | Meshtastic firmware < 2.7.23.b246bcd paired with iOS client |
| Fixed | 2.7.23.b246bcd — adds input sanitization and improved iOS handling |
| Exposure | No Shodan/Censys signal — LoRa mesh is RF, not IP-routable. Enterprise deployment: effectively 0% |
| Reporter | See GitHub advisory GHSA-gq7v-jr8c-mfr7 and related iOS advisory |
| Disclosed | 2026-07-19 / 2026-07-20 |
Sources.
Why this verdict
- Availability-only, user-recoverable: the CVSS vector itself confirms C:N/I:N; the only impact is an iOS app that has to purge one node entry.
- Attacker must be RF-adjacent to the mesh — no internet-scale reachability, no scanner-driven mass exploitation model.
- Role multiplier — none: Meshtastic is not on the high-value-role catalog (no IdP, hypervisor, PAM, backup, CA, EDR, network edge, SIEM, or OT controller role). Even in the worst deployment (SAR teams, off-grid comms), the chain ends in 'restart the app' — no fleet, tenant, or supply-chain reach.
- Installed base in enterprise ≈ 0% — Shodan/Censys have no visibility because LoRa isn't IP; MDM inventories almost never list Meshtastic. This breaks the CRITICAL/HIGH floor because the affected component is definitionally not enterprise infrastructure.
- Trivial recovery path via Python CLI or aging out the poisoned entry — no persistent state damage.
Why not higher?
HIGH would require either enterprise-relevant blast radius or active exploitation — neither exists. There is no confidentiality or integrity impact, no code execution, and no lateral movement. The vendor's 7.5 is technically CVSS-defensible but ignores that the affected population is essentially not the enterprise fleet noisgate advises on.
Why not lower?
IGNORE would be wrong for the rare organization that *does* deploy Meshtastic operationally — search-and-rescue teams, event comms, some field research programs. For those users the DoS is real and reproducible without exploitation skill, so LOW (not IGNORE) reflects that a fix should still land in the backlog.
Crowdsourced verification payload.
Run on any workstation with the meshtastic Python CLI installed and a USB-connected Meshtastic node. Invoke as ./check-cve-2026-42566.sh (no arguments, no root required). Confirms the connected node's firmware version against the fixed release.
#!/usr/bin/env bash
# noisgate check for CVE-2026-42566
# Requires: meshtastic-python CLI (pip install meshtastic)
# Usage: ./check-cve-2026-42566.sh
set -u
FIXED="2.7.23"
if ! command -v meshtastic >/dev/null 2>&1; then
echo "UNKNOWN: meshtastic CLI not installed (pip install meshtastic)"
exit 2
fi
INFO=$(meshtastic --info 2>/dev/null)
if [ -z "$INFO" ]; then
echo "UNKNOWN: no Meshtastic node detected on USB"
exit 2
fi
VER=$(echo "$INFO" | grep -Eo 'firmware_version[^"]*"[^"]+"' | head -1 | sed -E 's/.*"([^"]+)"/\1/')
if [ -z "$VER" ]; then
VER=$(echo "$INFO" | grep -iE 'firmware' | head -1)
fi
echo "Detected firmware: ${VER:-unknown}"
# Compare major.minor.patch numerically
norm() { echo "$1" | grep -Eo '^[0-9]+\.[0-9]+\.[0-9]+' ; }
CUR=$(norm "$VER")
if [ -z "$CUR" ]; then
echo "UNKNOWN: could not parse firmware version"
exit 2
fi
# lexical-safe compare
lowest=$(printf '%s\n%s\n' "$CUR" "$FIXED" | sort -V | head -1)
if [ "$lowest" = "$FIXED" ] && [ "$CUR" != "$FIXED" ]; then
echo "PATCHED: $CUR >= $FIXED"
exit 0
elif [ "$CUR" = "$FIXED" ]; then
echo "PATCHED: $CUR == $FIXED (verify build suffix b246bcd or later)"
exit 0
else
echo "VULNERABLE: $CUR < $FIXED.b246bcd"
exit 1
fi