CVE-2026-38820 Overview
CVE-2026-38820 is an unauthenticated OS command injection vulnerability in openNDS captive portal software before version 11.0.0. The flaw resides in libopennds.sh, where the fas query parameter on the /opennds_preauth/ endpoint is passed to shell execution without proper sanitization. An adjacent-network attacker can inject arbitrary shell commands and achieve code execution as the openNDS process, typically running with elevated privileges on captive portal gateways and Wi-Fi routers.
The issue is tracked under CWE-78 (OS Command Injection). No authentication is required, and the endpoint is reachable by any client associated with the captive portal network.
Critical Impact
Unauthenticated attackers on the adjacent network can execute arbitrary operating system commands on the captive portal gateway, leading to full device compromise.
Affected Products
- openNDS versions prior to 11.0.0
- Captive portal gateways and Wi-Fi hotspot routers running openNDS
- Embedded OpenWrt-based devices using openNDS as the authentication service
Discovery Timeline
- 2026-08-28 - CVE-2026-38820 published to NVD
- 2026-08-28 - Last updated in NVD database
Technical Details for CVE-2026-38820
Vulnerability Analysis
openNDS (Nodogsplash) is a captive portal implementation widely used on OpenWrt and Linux gateways. The /opennds_preauth/ endpoint invokes the libopennds.sh shell script to process incoming requests before authentication. The script accepts a fas query parameter carrying a base64-encoded payload used by the Forwarding Authentication Service (FAS).
Before version 11.0.0, libopennds.sh interpolated the query fragment directly into shell contexts without validating character content. Because the value is embedded in shell command constructions, an attacker can supply metacharacters such as backticks, $(...), semicolons, or pipes to break out of the intended context and execute arbitrary commands. The vulnerability requires no session, no cookies, and no prior interaction with the portal splash page.
Root Cause
The root cause is missing input validation on untrusted query string data before shell interpretation. The pre-authentication code path assumed the fas parameter contained only base64-safe characters, but did not enforce that assumption. Any request to /opennds_preauth/?fas=<payload> reached shell parsing with attacker-controlled bytes intact.
Attack Vector
Exploitation requires network adjacency, meaning the attacker must associate with the Wi-Fi network or otherwise reach the captive portal interface. Once connected, the attacker sends a single crafted HTTP GET request to the /opennds_preauth/ endpoint with a malicious fas parameter. Successful exploitation yields command execution as the openNDS process user, which typically has privileges to modify firewall rules and network configuration on the gateway.
# Patch from upstream commit 8c03750d9a17d601fa7bd03ae7cde20c7c8d1252
# forward_authentication_service/libs/libopennds.sh
query_type=${querystr:0:9}
if [ "$query_type" = "%3ffas%3d" ]; then
+
+ # Check for a valid b64encoded query string
+ querystrlen=$((${#querystr}))
+ query_frag=${querystr:10:($querystrlen - 2)}
+
+ query_frag=$(echo "$query_frag" | awk -F "%3d" '{printf "%s", $1}')
+ syslogmessage="query_frag [ $query_frag ]"
+ debugtype="debug"
+ write_to_syslog
+
+ syslogmessage="Probable attempted code injection detected"
+ debugtype="warn"
+
+ case $query_frag in
+ *[!A-Za-z0-9+/=]*) write_to_syslog; exit 1 ;; # contains invalid character → reject
+ esac
Source: openNDS commit 8c03750d. The patch extracts the query fragment, then rejects any input containing characters outside the base64 alphabet [A-Za-z0-9+/=] before further processing.
Detection Methods for CVE-2026-38820
Indicators of Compromise
- Syslog entries from openNDS containing Probable attempted code injection detected after the patch is applied
- HTTP requests to /opennds_preauth/ with fas parameter values containing shell metacharacters such as ;, |, `, $(, or URL-encoded equivalents like %3b, %7c, %60
- Unexpected child processes spawned by the openNDS binary or shell interpreters invoking network utilities such as wget, curl, nc, or busybox
- Modifications to /etc/config/ files or firewall rules on gateway devices without an administrator action
Detection Strategies
- Inspect web server and openNDS access logs for requests to /opennds_preauth/ whose fas parameter fails base64 validation
- Monitor for anomalous outbound connections originating from the captive portal gateway itself, which typically initiates minimal traffic
- Correlate syslog warn messages from libopennds.sh with subsequent process execution on the device
Monitoring Recommendations
- Forward gateway syslog to a centralized log platform and alert on openNDS warning events
- Baseline the process tree of the openNDS service and alert when it spawns unexpected shell utilities
- Track HTTP request volume and payload entropy on the /opennds_preauth/ endpoint to identify probing activity
How to Mitigate CVE-2026-38820
Immediate Actions Required
- Upgrade openNDS to version 11.0.0 or later on all captive portal gateways
- Audit affected devices for signs of prior exploitation, including unauthorized configuration or firewall changes
- Restrict administrative access to the gateway management interface to trusted management VLANs
- Isolate captive portal networks from internal corporate segments using firewall segmentation
Patch Information
The upstream fix is committed in openNDS commit 8c03750d and shipped in version 11.0.0. The patch validates the fas query fragment against the base64 alphabet and rejects any request containing characters outside [A-Za-z0-9+/=] before shell processing occurs. OpenWrt and downstream distributions should update the opennds package to the fixed release.
Workarounds
- Disable the openNDS captive portal service until patching is possible if the deployment can tolerate the outage
- Deploy a reverse proxy or web application firewall in front of /opennds_preauth/ that rejects fas values containing non-base64 characters
- Apply the upstream patch manually to forward_authentication_service/libs/libopennds.sh on devices that cannot receive a full package update
# Verify installed openNDS version on OpenWrt
opkg list-installed | grep opennds
# Upgrade to fixed release
opkg update
opkg upgrade opennds
# Confirm the service restarts cleanly with the patched binary
/etc/init.d/opennds restart
logread | grep opennds
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.