Executive Summary
Three critical vulnerabilities in Ubiquiti's UniFi OS Server — an authentication bypass (CVE-2026-34908), a path traversal (CVE-2026-34909), and a command injection (CVE-2026-34910) — can be chained together to allow any unauthenticated attacker with network access to execute arbitrary OS commands as root on affected devices. CISA added all three to its Known Exploited Vulnerabilities (KEV) catalog on June 23, 2026, citing active in-the-wild exploitation, with a mandatory remediation deadline of June 26, 2026 for federal civilian agencies. Organizations running UniFi OS Server 5.0.6 or earlier must patch immediately.
1. What Is This Vulnerability?
The attack is not a single flaw but a three-stage chain. Each vulnerability on its own is dangerous; together they produce a fully unauthenticated root shell on any exposed UniFi OS Server.
Stage 1 — Authentication Bypass (CVE-2026-34908 + CVE-2026-34909)
UniFi OS uses NGINX as its reverse proxy and front-end request router. The authentication module checks the raw URI of incoming requests, while NGINX routes based on the normalized URI. Attackers exploit this inconsistency by crafting requests that begin with an auth-exempt path prefix in raw form (e.g., /v/public/…/..), which the auth module passes through without a credentials check. After NGINX normalizes the URI (resolving .. traversal sequences), the request resolves to a protected internal endpoint.
CVE-2026-34908 (Improper Access Control, CVSS 10.0) allows the auth gate to be bypassed entirely. CVE-2026-34909 (Path Traversal, CVSS 10.0) is the directory traversal component that shifts the normalized path to the target endpoint. Together, they grant an unauthenticated attacker read/write access to privileged internal API routes and expose sensitive files from the underlying OS filesystem.
Stage 2 — Command Injection (CVE-2026-34910)
Once the auth bypass grants access to the ucs-update (UniFi OS package update) service endpoint, CVE-2026-34910 (Improper Input Validation, CVSS 9.8) takes over. The package-update function accepted a caller-supplied package name and passed it directly to a shell command without sanitization:
# Vulnerable pseudocode (before patch)
apt-get install -y $PACKAGE_NAME
An attacker supplies a crafted package name containing shell metacharacters — for example, ; id; # — causing the shell to execute arbitrary commands. The ucs-update process runs under a highly privileged service account that holds passwordless sudo access to several system binaries, making full root escalation trivial.
Attack Vector
The complete unauthenticated RCE chain requires only network access to the UniFi OS management port (typically HTTPS on port 443 or 8443):
- Send crafted request with traversal prefix → auth gate passes it, NGINX resolves to protected endpoint.
- Use the bypassed endpoint to read session tokens or configuration files via CVE-2026-34909.
- Call the
ucs-updateAPI endpoint (now accessible without credentials) with an injected package name. - Shell metacharacters execute as the update service account.
sudoescalation achieves root.
Bishop Fox researchers validated and published a full proof-of-concept write-up confirming root access is reliably achievable.
Real-World Impact
Active exploitation was confirmed prior to CISA's KEV addition. Threat actors gaining root on a UniFi OS Server (which serves as a network management hub controlling routers, switches, APs, cameras, and VPN gateways) can pivot to every downstream device on the network, exfiltrate configurations and credentials, establish persistent backdoors, or redirect traffic. Given that UniFi is widely deployed in SMBs, universities, healthcare, and hospitality networks, the blast radius is significant.
2. Who Is Affected?
| Product | Vulnerable Versions | Fixed Version |
|---|---|---|
| UniFi OS Server (generic) | ≤ 5.0.6 (unifi-core ≤ 5.0.126) | 5.0.8 (unifi-core 5.0.153) |
| UDM, UDM-Pro, UDM-SE, UDM-Pro-Max | Firmware < 5.1.12 | 5.1.12 |
| Cloud Key Gen2, Cloud Key Gen2+ | UniFi OS < 5.0.8 | 5.0.8 |
| UniFi Express | UniFi OS < 5.0.8 | 5.0.8 |
Risk multiplier: Any UniFi OS management interface exposed directly to the internet (including mistakenly port-forwarded HTTPS) is trivially exploitable by automated scanners. Shodan and similar tools index tens of thousands of such instances.
3. How to Detect It (Testing)
Manual Testing Steps
- Identify the UniFi OS Server version: Log in to the UniFi OS console, navigate to Settings → System → Updates, and note the reported OS Server version. Versions ≤ 5.0.6 are vulnerable.
- Check unifi-core build: SSH into the device and run
ubnt-daemon versionorcat /etc/unifi-os/version. Builds ≤ 5.0.126 are vulnerable. - Test auth bypass (safe passive check): Attempt to access
/v/public/../../../../api/v2/unifios/settingsfrom an unauthenticated session. On a patched system, this returns HTTP 401 or 403. On a vulnerable system, it returns 200 with settings data. Do not proceed to exploitation in production environments. - Review NGINX access logs for requests matching the pattern
GET /v/public/followed by repeated../sequences targeting protected routes.
Automated Scanning
Bishop Fox Detection Tool (passive — no command execution):
# Clone the official check tool
git clone https://github.com/BishopFox/CVE-2026-34908-check
cd CVE-2026-34908-check
# Run against target (replace with your UniFi OS host)
python3 check.py --host 192.168.1.1 --port 443
# Expected output for vulnerable host:
# [VULNERABLE] CVE-2026-34908 auth bypass confirmed on 192.168.1.1:443
# [VULNERABLE] CVE-2026-34909 path traversal reachable
Nessus / Tenable: Plugin IDs are available in the Tenable vulnerability database for CVE-2026-34908 and CVE-2026-34910 — run an authenticated or unauthenticated network scan against UniFi OS hosts.
Nuclei Template:
# Fetch community template
nuclei -t cves/2026/CVE-2026-34908.yaml -u https://192.168.1.1 -silent
Code Review Checklist
If you maintain custom UniFi OS integrations or plugins:
- All URI parsing compares normalized paths — never raw URIs — against auth allowlists
- Package names and any user-supplied strings passed to shell commands go through an allowlist or argument-array call (no shell interpolation)
- Internal API endpoints requiring authentication are not reachable via traversal path tricks
- Sudo rules for service accounts follow the principle of least privilege
4. How to Fix It (Mitigation)
Step-by-Step Remediation
- Log into the UniFi OS dashboard on each affected controller or gateway device.
- Navigate to Settings → System → Updates.
- Apply the available UniFi OS update and confirm the target version:
- UniFi OS Server → 5.0.8 (unifi-core 5.0.153 or later)
- UDM/UDM-Pro/UDM-SE/UDM-Pro-Max → firmware 5.1.12 or later
- Reboot the device after the update completes and verify the new version in Settings → System.
- For managed deployments using the UniFi Network Application, ensure the application itself is also updated and confirm that auto-update is enabled for all adopted devices.
- Audit firewall rules: Verify that the UniFi OS management interface (ports 443, 8443, 8080) is not exposed to the public internet. Restrict access to management IPs only.
- Rotate credentials: If the device may have been compromised before patching, rotate the UniFi admin password, change site-wide Wi-Fi PSKs, and revoke any API keys or OAuth tokens stored on the device.
Patch Technical Details
The patch makes two key changes:
CVE-2026-34908/34909 fix: The auth middleware was updated to normalize URIs before comparison, eliminating the raw vs. normalized discrepancy:
// After patch — auth module normalizes path before allowlist check
normalizedPath := path.Clean(r.URL.Path)
if !isPublicPath(normalizedPath) {
requireAuthentication(w, r)
return
}
CVE-2026-34910 fix: The package-update handler was rewritten to use an argument array rather than shell interpolation, and a package name allowlist was added:
// Before patch (vulnerable)
cmd := exec.Command("sh", "-c", "apt-get install -y " + packageName)
// After patch (safe)
if !isAllowedPackage(packageName) {
return errors.New("package not in allowlist")
}
cmd := exec.Command("apt-get", "install", "-y", packageName)
Configuration Hardening
Even before patching (as a temporary measure) and permanently after:
- Firewall: Block ports 443/8443/8080 from untrusted networks at the perimeter. Management access should require VPN.
- Disable remote management: In UniFi Network → Settings → System → Remote Access, disable cloud remote access unless strictly required.
- Enable 2FA on all UniFi accounts via Settings → Admins → Multi-Factor Authentication.
- Separate management VLAN: Place the UniFi OS controller on an isolated management VLAN not reachable from guest or IoT networks.
5. How to Test the Fix (Validation)
Regression Test Scenarios
- Scenario A (patch confirmation): After updating to 5.0.8+, run the Bishop Fox detection tool — expected result:
NOT VULNERABLEon all hosts. - Scenario B (auth bypass test): Send an unauthenticated request with traversal sequences to the protected settings endpoint — expected result: HTTP 401 Forbidden.
- Scenario C (command injection test): Using Burp Suite, attempt to inject shell metacharacters (
; id) into any API parameter that previously reached the package manager — expected result: the request is rejected with an error; no command output is returned. - Scenario D (functional regression): After patching, confirm that legitimate package updates via the UniFi UI still succeed — install a test package update through the normal update workflow.
Security Test Cases
Test Case 1: Verify auth bypass is closed
- Precondition: UniFi OS Server updated to 5.0.8+
- Steps:
- Open Burp Suite and proxy a request to
https://<unifi-host>/v/public/../../../../api/v2/unifios/settingswithout authentication headers. - Send the request.
- Open Burp Suite and proxy a request to
- Expected Result: HTTP 401 Unauthorized (not 200 OK with data)
Test Case 2: Verify command injection is mitigated
- Precondition: UniFi OS Server updated to 5.0.8+
- Steps:
- Authenticate to the management API.
- Send a POST request to the ucs-update endpoint with
packageName: "bash; id #".
- Expected Result: HTTP 400 Bad Request or a package-not-in-allowlist error; no command is executed.
Automated Tests
import requests
import urllib3
urllib3.disable_warnings()
UNIFI_HOST = "https://192.168.1.1"
def test_auth_bypass_patched():
"""CVE-2026-34908/34909: auth bypass should return 401 after patch."""
url = f"{UNIFI_HOST}/v/public/../../../../api/v2/unifios/settings"
resp = requests.get(url, verify=False, timeout=5)
assert resp.status_code == 401, \
f"FAIL: Auth bypass still open! Got HTTP {resp.status_code}"
print("PASS: CVE-2026-34908/34909 auth bypass is closed.")
def test_command_injection_patched():
"""CVE-2026-34910: shell metacharacters should be rejected."""
url = f"{UNIFI_HOST}/api/v2/unifios/updates/packages"
payload = {"packageName": "bash; id #"}
resp = requests.post(url, json=payload, verify=False, timeout=5)
assert resp.status_code in (400, 401, 403), \
f"FAIL: Injection payload accepted! Got HTTP {resp.status_code}"
assert "id" not in resp.text.lower() or "uid=" not in resp.text, \
"FAIL: Command output found in response — injection still works!"
print("PASS: CVE-2026-34910 command injection is blocked.")
if __name__ == "__main__":
test_auth_bypass_patched()
test_command_injection_patched()
6. Prevention & Hardening
Best Practices
- Network segmentation is your first line of defense. UniFi OS management should never be reachable from the internet. Use a dedicated management VLAN and require VPN for remote access. This single control would have prevented the majority of real-world exploitations.
- Subscribe to Ubiquiti security bulletins. Ubiquiti publishes security advisories in the Community Security Advisory board. Subscribe and treat Critical bulletins as emergency patching events.
- Adopt an asset inventory for network gear. Unmanaged or forgotten UniFi devices running outdated firmware are the most vulnerable. Run quarterly audits of all UniFi deployments across your organization.
- Principle of least privilege for service accounts. The CVE-2026-34910 impact was magnified because the update service held passwordless sudo access. Review sudo rules on all Unix-based appliances in your environment.
- Enable auto-update for non-production UniFi networks. Delayed patching windows are acceptable for production networks needing change control, but home labs, branch offices, and demo environments should auto-update.
Monitoring & Detection
Once patched, monitor for signs that exploitation was attempted or succeeded:
NGINX access log patterns to alert on:
# Search for traversal attempts in NGINX logs
grep -E 'GET /v/public/(\.\./)+' /var/log/nginx/access.log
# Alert on unexpected 200 responses to auth-exempt paths
awk '$9 == 200 && $7 ~ /\/v\/public\/.*\/\.\./' /var/log/nginx/access.log
System-level indicators of compromise (IoC):
- Unexpected processes spawned by
ucs-update(e.g.,bash,curl,wget,nc, Python/Perl reverse shells) - New cron entries, SSH authorized keys, or users added to
/etc/passwd - Outbound connections on unusual ports originating from the UniFi OS host
- Modified files under
/etc/unifi-os/or/data/
SIEM rules (Sigma format):
title: UniFi OS Auth Bypass Attempt (CVE-2026-34908)
status: stable
description: Detects path traversal attempts against UniFi OS auth gateway
logsource:
category: webserver
product: nginx
detection:
keywords:
- '/v/public/../'
- '/v/public/../../'
condition: keywords
falsepositives:
- None expected
level: high
tags:
- cve.2026.34908
- attack.initial_access
References
- CISA KEV Entry: CISA Adds Ubiquiti UniFi OS Flaws to KEV Catalog
- Official Ubiquiti Advisory: Security Advisory Bulletin 064 — Ubiquiti Community
- Bishop Fox Research / Detection Tool: Popping Root on UniFi OS Server — Bishop Fox | GitHub: CVE-2026-34908-check
- BleepingComputer Coverage: Critical UniFi OS bug lets hackers gain root without authentication
- SecurityWeek Analysis: Critical Ubiquiti Vulnerabilities in Attackers' Crosshairs
- CVE-2026-34910 Patch Detail: TechJack Solutions CVE-2026-34910 Analysis
- CISA BOD 26-04: Binding Operational Directive 26-04 — Prioritizing Security Updates Based on Risk