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.
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.
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:
case management.ClientAuthDeny:
// ... writes "0" to auth_control_file ...
if err := openVPNClient.WriteToAuthFile("0"); err != nil {
// only returned ERROR on write failure
return...
1.27.3Exploitability
AV:NAC:LPR:NUI:NScope
S:CImpact
C:HI:HA:N10.0/CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N