CVE-2026-74994 Overview
CVE-2026-74994 is an authorization flaw [CWE-863] in the mod_auth module of Erlang/OTP's inets httpd server. When administrators configure the server with dets or mnesia authentication backends and define multiple directory blocks, the module collapses every directory into a single shared user and group namespace. A user provisioned for one protected directory is therefore accepted as valid across every other protected directory served by the same instance.
The issue affects OTP 17.0 through 27.3.4.16, OTP 28.0 through 28.5.0.5, and OTP 29.0 through 29.0.5, corresponding to inets versions 5.10 through 9.3.2.6, 9.4 through 9.6.2.2, and 9.7 through 9.7.1.
Critical Impact
Any authenticated user in one protected directory can access all other protected directories on the same inets server, breaking per-directory access boundaries.
Affected Products
- Erlang/OTP 17.0 before 27.3.4.17 (inets 5.10 before 9.3.2.7)
- Erlang/OTP 28.0 before 28.5.0.6 (inets 9.4 before 9.6.2.3)
- Erlang/OTP 29.0 before 29.0.6 (inets 9.7 before 9.7.2)
Discovery Timeline
- 2026-09-01 - CVE CVE-2026-74994 published to NVD
- 2026-09-01 - Last updated in NVD database
Technical Details for CVE-2026-74994
Vulnerability Analysis
The inets httpd server supports multiple directory configuration blocks, each intended to define an isolated authentication scope. When mod_auth uses the dets or mnesia backends, the server dispatches authentication calls without carrying the directory path into the backend lookup. As a result, user and group records inserted for one directory scope are queryable from any directory scope on the same server instance.
This breaks the least-privilege model that operators expect when partitioning HTTP resources by directory. An attacker holding credentials for a low-sensitivity directory can present those credentials to a higher-sensitivity directory and be authorized, provided the target directory also uses dets or mnesia. The vulnerability applies only when both conditions hold: a dets or mnesia backend is configured, and more than one directory block exists.
Root Cause
The check_password/4 function in mod_auth.erl discarded the Dir argument (named _Dir) and looked up users using only the shared DirData. Similarly, the dispatch path in mod_auth_server.erl invoked backend functions with DirData alone, providing no directory scoping key. Without the directory path in the lookup context, dets and mnesia tables served records from a single global namespace.
Attack Vector
The attack requires network access to the inets httpd endpoint and valid credentials for any one of the protected directories. The attacker submits a standard HTTP request with Authorization credentials against a different protected directory URL on the same server. Because the backend lookup ignores the directory scope, mod_auth accepts the credential and grants access.
// Patch: lib/inets/src/http_server/mod_auth.erl
// Pass directory path into user lookup for scope isolation
-check_password(User, Password, _Dir, DirData) ->
- case int_get_user(DirData, User) of
+check_password(User, Password, Dir, DirData) ->
+ DirDataWithPath = [{path, Dir} | DirData],
+ case int_get_user(DirDataWithPath, User) of
{ok, UStruct} ->
case UStruct#httpd_user.password of
Password ->
// Patch: lib/inets/src/http_server/mod_auth_server.erl
// Prepend directory path to DirData before dispatching to backend
case ets:match_object(ConfigName, {directory, {Dir, '$1'}}) of
[{directory, {Dir, DirData}}] ->
AuthMod = auth_mod_name(DirData),
- (catch apply(AuthMod, Func, [DirData|Args]));
+ DirDataWithPath = [{path, Dir} | DirData],
+ (catch apply(AuthMod, Func, [DirDataWithPath|Args]));
_ ->
{error, no_such_directory}
end;
Source: GitHub commit 6101cb74
Detect Identity Attacks the Moment Authentication Fails
Singularity™ Identity surfaces credential misuse, lateral movement, and privilege escalation in real time, so you can contain the breach before it spreads.
Stop Identity AttacksDetection Methods for CVE-2026-74994
Indicators of Compromise
- Successful HTTP 200 responses to protected paths preceded by Authorization headers using credentials that were provisioned for a different directory scope.
- inets access logs showing the same username authenticating against multiple distinct directory paths in a short window.
- Unexpected 2xx responses from directories that should be limited to a smaller user cohort.
Detection Strategies
- Inventory all inets httpd deployments and identify configurations that combine dets or mnesia backends with two or more directory blocks.
- Correlate authenticated request patterns per user across directory paths and flag users accessing directories outside of their expected scope.
- Compare deployed OTP and inets versions against the fixed releases: OTP 27.3.4.17, 28.5.0.6, 29.0.6 and inets9.3.2.7, 9.6.2.3, 9.7.2.
Monitoring Recommendations
- Enable verbose access logging on inets httpd and forward logs to a centralized analytics platform for cross-directory correlation.
- Alert on first-time access events where a user authenticates to a directory they have never accessed before.
- Track configuration drift on any node running Erlang services to catch unmanaged mod_auth deployments.
How to Mitigate CVE-2026-74994
Immediate Actions Required
- Upgrade Erlang/OTP to 27.3.4.17, 28.5.0.6, or 29.0.6 depending on your release branch.
- Audit mod_auth directory blocks and remove users whose scope cannot be validated post-upgrade.
- Rotate any credentials that may have been used to reach directories outside their intended scope.
Patch Information
The upstream fix threads the directory path into mod_auth backend calls by prepending {path, Dir} to DirData before invoking the authentication module. See the Erlang/OTP security advisory GHSA-c3cq-q8x6-547g and the CNA advisory for CVE-2026-74994 for the fixed release matrix. Commits are available at 6101cb74, 6982e381, and c5ccec8e.
Workarounds
- Consolidate protected content into a single directory block until the patched OTP release can be deployed.
- Switch the mod_auth backend from dets or mnesia to plain where feasible, since the flaw is scoped to dets/mnesia shared namespaces.
- Place a reverse proxy in front of inets and enforce per-path authentication at the proxy layer to restore directory isolation.
# Verify installed Erlang/OTP version and inets application version
erl -eval 'io:format("OTP: ~s~n", [erlang:system_info(otp_release)]), \
application:load(inets), \
{ok, Vsn} = application:get_key(inets, vsn), \
io:format("inets: ~s~n", [Vsn]), \
halt().' -noshell
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

