GitHub Advisoryadvisory · Go

GHSA-246w-jgmq-88fg openvpn-auth-oauth2 returns FUNC_SUCCESS on client-deny, allowing unauthenticated VPN access

CRITICAL Published 2026-04-22 Modified 2026-05-13 Official page ↗
Aliases
CVE-2026-41070
Ecosystem
Go
Packages
github.com/jkroepke/openvpn-auth-oauth2
Severity
Critical
CVSS vector
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N
Weaknesses
CWE-287
Reviewed
2026-04-22

Affected packages

• Go github.com/jkroepke/openvpn-auth-oauth2: >= 1.26.3, < 1.27.3 → fixed in 1.27.3

Description

Summary When `openvpn-auth-oauth2` is deployed in the experimental plugin mode (shared library loaded by OpenVPN via the `plugin` directive), clients that do not support WebAuth/SSO (e.g., the `openvpn` CLI on Linux) are incorrectly admitted to the VPN despite being denied by the authentication logic. The default management-interface mode is not affected because it does not use the OpenVPN plugin return-code mechanism. Impact Authentication bypass — any VPN client that does not advertise WebAuth/SSO support (`IV_SSO=webauth`) is granted full network access without completing OIDC authentication. This affects only deployments running the experimental plugin mode in versions 1.26.3 through 1.27.2. The default and recommended deployment via the management interface is not affected. An unauthenticated attacker can connect to the OpenVPN server using any standard OpenVPN client that does not support webauth (e.g., the Linux `openvpn` CLI). The plugin correctly issues a `client-deny` command via the management interface, but returns `OPENVPN_PLUGIN_FUNC_SUCCESS` (status=0) to OpenVPN. Because the `auth_control_file` content is only consulted when the plugin returns `FUNC_DEFERRED`, OpenVPN interprets status=0 as "authentication passed" and admits the client — granting full access to the internal network behind the VPN. Root Cause In `lib/openvpn-auth-oauth2/openvpn/handle.go`, the `ClientAuthDeny` branch of `handleAuthUserPassVerify` wrote `"0"` (deny) to the `auth_control_file` but returned `OPENVPN_PLUGIN_FUNC_SUCCESS`. OpenVPN only reads the `auth_control_file` when the plugin returns `FUNC_DEFERRED`; a synchronous `FUNC_SUCCESS` return is treated as immediate approval regardless of file contents. Before fix: ```go case management.ClientAuthDeny: // ... writes "0" to auth_control_file ... if err := openVPNClient.WriteToAuthFile("0"); err != nil { // only returned ERROR on write failure return c.OpenVPNPluginFuncError } return c.OpenVPNPluginFuncSuccess // ← BUG: OpenVPN sees this as "auth passed" ``` After fix (commit `36f69a6`): ```go case management.ClientAuthDeny: // ... writes "0" to auth_control_file ... if err := openVPNClient.WriteToAuthFile("0"); err != nil { logger.ErrorContext(p.ctx, "write to auth file", slog.Any("err", err)) } return c.OpenVPNPluginFuncError // ← FIX: OpenVPN now correctly rejects the client ``` Patches This vulnerability is fixed in v1.27.3. Users of the experimental plugin mode should upgrade immediately. • Fix commit: `36f69a6` • Fix PR: #829 Workarounds • Switch to standalone management client mode (the default, non-plugin deployment). This mode is not affected by the vulnerability because authentication decisions are communicated entirely through the management interface protocol, not through the plugin return code. • Restrict VPN access at the network level to only clients known to support WebAuth/SSO (e.g., OpenVPN Connect 3+), although this is difficult to enforce reliably and is not recommended as a sole mitigation.

Related

Alias · CVE (1)

  • CVE-2026-41070 openvpn-auth-oauth2 is a plugin/management interface client for OpenVPN server to handle an OIDC based single sign-on (SSO) auth flows. vulnerability

Weakness · CWE (1)

  • CWE-287 Improper Authentication weakness

References