← Back to Feed CACHED · 2026-09-25 03:22:07 · CACHE_KEY CVE-2026-93291
CVE-2026-93291 · CWE-295 · Disclosed 2026-09-24

Omni C20 lacks proper certificate validation which could

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

Your robot vacuum trusts any certificate like a toddler trusts any stranger in a costume

CVE-2026-93291 is an improper certificate validation flaw (CWE-295) in the Eufy Omni C20 and Omni X10 Pro consumer robot vacuums running firmware prior to version 1.6.4. The device fails to validate TLS certificates when communicating with its cloud backend. An attacker who achieves man-in-the-middle positioning on the same network segment can present a self-signed or otherwise invalid certificate, intercept and modify traffic in transit, and ultimately inject payloads that achieve arbitrary code execution on the device. The flaw was reported by Jared of Somerset Recon and disclosed via CISA ICS advisory ICSA-26-267-02 on September 24, 2026. It is part of a trio of bugs (alongside CVE-2026-93289 for command injection and CVE-2026-93290 for hardcoded credentials) affecting the same product line.

The vendor CVSS of 9.4 CRITICAL is detached from enterprise reality. The score is mechanically derived from AV:N/AC:L/PR:N/UI:N, which implies a trivially exploitable internet-facing service — but the actual attack requires man-in-the-middle positioning on the local network where a *consumer robot vacuum* operates. That is not AC:L in any honest reading; it presupposes local network access via ARP spoofing, DNS poisoning, or a rogue access point. More fundamentally, the affected component is a home appliance. It is not an identity provider, a domain controller, a hypervisor, a backup server, or any other high-value enterprise asset. For a security team managing 10,000 hosts, the probability that a Eufy Omni C20 appears in their CMDB is near zero, and if it does, the blast radius of compromising it is confined to a single IoT device on (hopefully) a segmented VLAN. The 9.4 CRITICAL label will waste triage cycles if left uncontested.

"A robot vacuum cert flaw scored like a domain takeover — irrelevant to enterprise fleets."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Attain local network access

The attacker must first be positioned on the same Layer 2 network segment as the Eufy Omni C20. This requires either physical proximity to join the Wi-Fi network, compromise of the Wi-Fi PSK, ARP cache poisoning from another compromised host, or deployment of a rogue access point. The vacuum connects only on 2.4 GHz Wi-Fi, further constraining the attack surface.
Conditions required:
  • Physical proximity to target Wi-Fi network or prior compromise of a host on the same LAN
  • Knowledge of Wi-Fi PSK or ability to deploy a rogue AP
Where this breaks in practice:
  • Enterprise networks with 802.1X / WPA3 block rogue devices
  • IoT devices should be on segmented VLANs unreachable from attacker workstations
  • Most enterprises do not operate consumer robot vacuums on production networks
Detection/coverage: Wireless IDS (e.g., Cisco CleanAir, Aruba WIDS) detects rogue APs. NAC solutions block unauthorized devices.
STEP 02

Establish man-in-the-middle position

From the local network, the attacker performs ARP spoofing or DNS poisoning to intercept traffic between the Eufy vacuum and its cloud API endpoint. Tools like bettercap or mitmproxy are standard for this. The attacker must sustain the MitM for the duration of the exploit, which requires ongoing network presence.
Conditions required:
  • Active Layer 2 access on the vacuum's VLAN
  • No dynamic ARP inspection (DAI) or DHCP snooping enabled on the switch
Where this breaks in practice:
  • Managed switches with DAI and DHCP snooping defeat ARP-based MitM
  • DNS-based MitM is blocked by DNS-over-HTTPS or internal DNS security policies
  • The vacuum may not generate frequent cloud traffic, limiting interception windows
Detection/coverage: ARP anomaly detection in switches or network monitoring tools (e.g., Darktrace, ExtraHop) flags ARP spoofing.
STEP 03

Present fraudulent TLS certificate

When the vacuum initiates a TLS connection to its cloud backend, the attacker intercepts the handshake and presents a self-signed or attacker-controlled certificate. Due to CVE-2026-93291, the vacuum accepts the certificate without validation, completing the TLS session with the attacker as a transparent proxy.
Conditions required:
  • Sustained MitM position from Step 2
  • Vacuum initiates outbound TLS connection during the interception window
Where this breaks in practice:
  • The vacuum must be actively communicating — not idle or powered off
  • Certificate pinning on the cloud-side does not help here since the *client* is the one failing validation
Detection/coverage: Network sensors monitoring for TLS certificate anomalies (mismatched CN/SAN, self-signed certs to known cloud endpoints) can flag this.
STEP 04

Inject malicious payload for code execution

With full MitM control over the TLS session, the attacker modifies cloud responses to inject a malicious payload — potentially a firmware update, command directive, or crafted API response that triggers code execution on the vacuum's embedded Linux system. The exact payload mechanism depends on the vacuum's update protocol, which Somerset Recon did not publicly detail. No public PoC exists for this step.
Conditions required:
  • Full TLS MitM from Step 3
  • Knowledge of the vacuum's cloud protocol and payload format (not publicly documented)
Where this breaks in practice:
  • No public PoC or exploit code exists
  • Requires reverse engineering of proprietary Eufy cloud protocol
  • Payload must be crafted for the specific embedded ARM/MIPS firmware
Detection/coverage: Endpoint-level detection is not applicable — consumer IoT devices do not run EDR agents.
03 · Intelligence Metadata

The supporting signals.

In-the-wild exploitationNone reported. CISA states no known public exploitation as of disclosure. Not observed in any threat campaign.
Proof-of-conceptNo public PoC. Somerset Recon (Jared) reported the flaw through coordinated disclosure to CISA. No exploit code, write-up, or reproduction steps have been published.
EPSS scoreNot yet scored. CVE was reserved 2026-09-17 and published 2026-09-24 — EPSS typically lags 7–14 days. Expected to be very low (<0.01) given IoT niche and no PoC.
KEV statusNot listed. No CISA Known Exploited Vulnerabilities catalog entry as of 2026-09-25.
CVSS vectorCVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:L — 9.4. The AV:N and AC:L are misleading: practical exploitation requires MitM positioning on the local network, which is closer to AV:A/AC:H in reality.
Affected versionsEufy Omni C20 and Omni X10 Pro, all firmware versions < 1.6.4.
Fixed versionFirmware 1.6.4 — delivered via Eufy app OTA update.
Scanning / exposureNot applicable. The Eufy Omni C20 is a consumer robot vacuum. It does not expose listening ports to the internet. Shodan/Censys/GreyNoise have zero relevant results — the device is a Wi-Fi client, not a server.
Disclosure date2026-09-24 via CISA ICS advisory ICSA-26-267-02. CVE reserved 2026-09-17.
Reporting researcherJared of Somerset Recon, reported to CISA via coordinated disclosure. Also reported CVE-2026-93289 (command injection) and CVE-2026-93290 (hardcoded credentials) in the same product.

Sources.

  1. CISA ICS Advisory ICSA-26-267-02
  2. TheHackerWire — CVE-2026-93291 MITM to RCE Analysis
  3. SecurityOnline — Eufy Robot Vacuum Vulnerabilities
  4. OffSeq Threat Radar — CVE-2026-93291
  5. Strix.ai — CVE-2026-93291 Details
  6. Eufy Omni C20 Product Page
  7. Patrick Coyle — CISA Advisories Published 9-24-26
04 · The Call

Final Verdict
↓ DOWNGRADED to LOW (2.5/10)

Why this verdict

  • MitM prerequisite is not AC:L. The CVSS vector claims AV:N/AC:L, but exploitation requires the attacker to achieve man-in-the-middle positioning on the device's local Wi-Fi segment. This demands either physical proximity, a compromised host on the same VLAN, or a rogue AP — each of which implies prior access. In enterprises with 802.1X, WPA3, DAI, and IoT segmentation, this is AC:H at best and often infeasible. Adjustment: −2.0 from baseline.
  • Consumer IoT device with near-zero enterprise footprint. The Eufy Omni C20 is a $250 robot vacuum sold at Walmart. It does not appear in enterprise CMDBs, is not managed by endpoint management tools, and is not part of any business-critical workflow. The probability of encountering one on a 10,000-host enterprise network is negligible. Even in smart-office scenarios, it would be a single unmanaged IoT device. Adjustment: −3.0 from baseline.
  • No PoC, no exploitation, no tooling. There is no public exploit code, no documented reproduction path, and no known campaign targeting this vulnerability. The attacker would need to reverse-engineer Eufy's proprietary cloud protocol to weaponize the MitM into code execution. This is not a one-click exploit. Adjustment: −1.0 from baseline.
  • Role multiplier: no high-value role applies. The Eufy Omni C20 is a consumer appliance. It cannot serve as an identity provider, domain controller, hypervisor, backup server, PKI/CA, CI/CD runner, database tier, EDR agent, network edge appliance, SIEM, or OT/SCADA controller. 100% of its installed base occupies the lowest-value role possible — a home cleaning appliance. The blast radius of compromise is a single IoT device: no domain takeover, no fleet compromise, no supply-chain pivot, no data exfiltration of regulated data. The high-value role floor does NOT apply. Compromise yields: access to home floor-mapping data and a potential (but limited) network pivot point on a consumer Wi-Fi segment.
  • CISA ICS classification is a red herring. CISA ICS-CERT publishes advisories for all embedded/IoT devices under its charter, including consumer products. The ICS label does not mean this device is deployed in industrial control environments. No evidence of Eufy robot vacuums in OT/ICS/SCADA environments exists.

Why not higher?

The vulnerability is technically real and the cert validation failure is a legitimate CWE-295 flaw. If an attacker achieves MitM on the same network and can reverse-engineer the cloud protocol, code execution is plausible. However, every step in the chain requires conditions that are either extremely unlikely in enterprise environments (the device being present at all) or blocked by standard network security controls (802.1X, VLAN segmentation, DAI). The blast radius — a single robot vacuum — does not justify anything above LOW.

Why not lower?

IGNORE would be defensible for most enterprises, but if your organization has deployed IoT vacuums on corporate Wi-Fi (smart offices, executive suites, coworking spaces), the MitM → RCE chain is real and the compromised device could serve as a minimal network foothold. The CISA advisory also creates a compliance checkbox that some frameworks require tracking. LOW rather than IGNORE accounts for the non-zero possibility of presence and the regulatory paper trail.

05 · Compensating Control

1
LOW 2.5→IGNORE 0.5
SEVERITY REDUCED
Segment IoT devices onto a dedicated VLAN with no lateral access to production networks — Place any consumer IoT devices — including robot vacuums — on a purpose-built IoT VLAN with ACLs blocking all east-west traffic to corporate subnets. This eliminates the device as a pivot point even if compromised. Since this is rated LOW, there is no noisgate mitigation SLA — go straight to your standard IoT hygiene schedule.
2
LOW 2.5→IGNORE 0.5
SEVERITY REDUCED
Enable Dynamic ARP Inspection and DHCP Snooping on switch infrastructure — DAI and DHCP snooping on managed switches defeat ARP-based MitM attacks, breaking Step 2 of the attack chain entirely. This is a network-infrastructure control that protects all devices on the segment, not just the vacuum. Deploy as part of standard network hardening.
3
LOW 2.5→IGNORE 0.0
SEVERITY REDUCED
Apply firmware update 1.6.4 via the Eufy app — The definitive fix. Firmware 1.6.4 adds proper certificate validation. Updates are delivered OTA through the Eufy Clean mobile app. Since consumer IoT updates are owner-initiated, coordinate with facilities or office management to trigger the update. LOW verdict means no noisgate mitigation SLA — fold this into your backlog and remediate within the 365-day window or as part of routine IoT firmware reviews.
What doesn't work
  • Network-level TLS inspection / SSL proxy — the vacuum uses its own TLS stack to connect to Eufy cloud services; enterprise SSL inspection proxies would need to MitM the vacuum themselves, which ironically is the same attack the CVE describes. The proxy cannot force the vacuum to validate a different certificate chain.
  • EDR / endpoint protection — the Eufy Omni C20 is an embedded Linux device. No enterprise EDR agent runs on it. Host-based detection is not possible.
  • Vulnerability scanning (Nessus, Qualys, Rapid7) — standard enterprise vulnerability scanners do not have plugins for consumer robot vacuum firmware versions. These devices will not appear in scan results.
06 · Verification

Crowdsourced verification payload.

Run this script from any workstation on the same network as the Eufy vacuum. It attempts to identify Eufy devices via mDNS/UPnP and check their advertised firmware version. Requires Python 3.6+ and no special privileges. Example: python3 check_eufy_cve_2026_93291.py --subnet 192.168.1.0/24

noisgate-verify.py
PYTHONREAD-ONLYSAFE
#!/usr/bin/env python3
"""CVE-2026-93291 checker — Eufy Omni C20 / X10 Pro firmware version audit.
Scans local subnet for Eufy devices and checks firmware against fixed version 1.6.4.
Usage: python3 check_eufy_cve_2026_93291.py --subnet 192.168.1.0/24
Exit codes: 0=PATCHED/no devices, 1=VULNERABLE, 2=UNKNOWN
"""
import argparse
import ipaddress
import socket
import sys
import struct
import json
import re

FIXED_VERSION = (1, 6, 4)
TIMEOUT = 2
SSDP_ADDR = "239.255.255.250"
SSDP_PORT = 1900

def parse_version(ver_str):
    parts = re.findall(r'(\d+)', ver_str)
    if len(parts) >= 3:
        return tuple(int(p) for p in parts[:3])
    return None

def ssdp_discover(subnet):
    """Send SSDP M-SEARCH and look for Eufy devices."""
    msg = (
        'M-SEARCH * HTTP/1.1\r\n'
        'HOST: 239.255.255.250:1900\r\n'
        'MAN: "ssdp:discover"\r\n'
        'MX: 2\r\n'
        'ST: ssdp:all\r\n'
        '\r\n'
    )
    sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
    sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    sock.settimeout(TIMEOUT + 1)
    sock.sendto(msg.encode(), (SSDP_ADDR, SSDP_PORT))
    devices = []
    try:
        while True:
            data, addr = sock.recvfrom(4096)
            response = data.decode('utf-8', errors='ignore').lower()
            if 'eufy' in response or 'anker' in response or 'omni' in response:
                devices.append({'ip': addr[0], 'response': data.decode('utf-8', errors='ignore')})
    except socket.timeout:
        pass
    sock.close()
    return devices

def check_device(device):
    """Parse SSDP response for firmware version info."""
    resp = device.get('response', '')
    ver_match = re.search(r'(?:firmware|fw|version)[:/\s]*(\d+\.\d+\.\d+)', resp, re.IGNORECASE)
    if ver_match:
        ver = parse_version(ver_match.group(1))
        if ver:
            return ver
    return None

def main():
    parser = argparse.ArgumentParser(description='CVE-2026-93291 Eufy Omni C20 checker')
    parser.add_argument('--subnet', default='192.168.1.0/24', help='Subnet to scan (default: 192.168.1.0/24)')
    args = parser.parse_args()
    
    print(f"[*] Scanning for Eufy devices via SSDP on {args.subnet}...")
    devices = ssdp_discover(args.subnet)
    
    if not devices:
        print("[*] No Eufy/Anker IoT devices found on this network segment.")
        print("[*] If you know Eufy Omni C20/X10 Pro devices are present, check firmware")
        print("    version manually in the Eufy Clean app: Settings > Device Info > Firmware.")
        print("    Fixed version: >= 1.6.4")
        print("")
        print("UNKNOWN — no Eufy devices detected via SSDP; verify manually.")
        sys.exit(2)
    
    vulnerable = False
    unknown = False
    
    for dev in devices:
        ip = dev['ip']
        ver = check_device(dev)
        if ver is None:
            print(f"[?] Eufy device at {ip} — firmware version not parseable from SSDP.")
            print(f"    Check manually in Eufy Clean app. Fixed version: >= 1.6.4")
            unknown = True
        elif ver < FIXED_VERSION:
            print(f"[!] VULNERABLE — Eufy device at {ip} running firmware {'.'.join(map(str, ver))} (< 1.6.4)")
            vulnerable = True
        else:
            print(f"[+] PATCHED — Eufy device at {ip} running firmware {'.'.join(map(str, ver))} (>= 1.6.4)")
    
    print("")
    if vulnerable:
        print("VULNERABLE — one or more Eufy devices need firmware update to >= 1.6.4.")
        sys.exit(1)
    elif unknown:
        print("UNKNOWN — could not determine firmware version for all devices.")
        sys.exit(2)
    else:
        print("PATCHED — all detected Eufy devices are on firmware >= 1.6.4.")
        sys.exit(0)

if __name__ == '__main__':
    main()
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously