Introduction
A single crafted cookie is all it takes to gain full administrative control over AdGuard Home instances running on GL.iNet routers, granting an attacker the ability to manipulate DNS resolution for every device on the network. CVE-2026-41448, scored at CVSS v3 9.4 and CVSS v4 9.2, is a path traversal authentication bypass in AdGuard Home's authglinet middleware that turns an unsanitized file path into a complete security failure.
AdGuard Home is an open source, network wide DNS filtering server that blocks ads and tracking at the DNS level for all devices on a network without requiring client side software. It has a substantial user base, particularly through its integration with GL.iNet routers (models like the Flint 3, Beryl 7, and Slate 7), where it ships as the built in DNS filtering layer. This makes it a critical piece of network infrastructure in home and small business environments worldwide.
Technical Information
Root Cause: Unsanitized Path Construction from Cookie Input
CVE-2026-41448 is classified under CWE-22: Improper Limitation of a Pathname to a Restricted Directory. The vulnerability exists exclusively when AdGuard Home is launched with the --glinet command line flag, which activates the authglinet middleware. This middleware is a separate authentication module designed specifically for GL.iNet router integration.
The core issue is straightforward: the middleware constructs a filesystem path by concatenating a static prefix with the value of the Admin-Token cookie, then opens that path to read and validate the authentication token. Prior to the patch, the prefix was defined as a mutable package level variable:
// BEFORE (internal/home/authglinet.go) var glFilePrefix = "/tmp/gl_token_"
When a request arrived, the cookie value was appended directly to this prefix to form the full file path. No sanitization, no validation, no directory confinement. A cookie value containing ../ sequences would cause the resulting path to escape the intended /tmp/ directory entirely.
Attack Flow
The exploitation sequence is direct:
- The attacker identifies an AdGuard Home instance running with the
--glinetflag (the default on GL.iNet routers). - The attacker sends an HTTP request to the AdGuard Home web interface with a crafted
Admin-Tokencookie containing path traversal sequences (e.g.,../../followed by a known file path). - The
authglinetmiddleware concatenates this unsanitized cookie value with the/tmp/gl_token_prefix, producing a path like/tmp/gl_token_/../../etc/some_file. - The middleware opens this traversed path using
os.Openand reads its contents. - If the file read succeeds and the returned content satisfies the token validation logic, the middleware grants full administrative access.
- The attacker now has complete control over the AdGuard Home instance: DNS filtering rules, upstream DNS servers, DHCP settings, and all connected device DNS resolution.
CVSS Scoring
The CVSS v4 vector assigned by VulnCheck is CVSS:4.0/AV:N/AC:L/AT:P/PR:N/UI:N/VC:H/VI:H/VA:L/SC:N/SI:N/SA:N. The AT:P (Attack Requirements: Present) reflects the requirement that the target must be running with the --glinet flag. On GL.iNet routers, this is the default configuration, making it a condition rather than a barrier.
| Metric | Value |
|---|---|
| Attack Vector | Network |
| Attack Complexity | Low |
| Privileges Required | None |
| User Interaction | None |
| Confidentiality Impact | High |
| Integrity Impact | High |
| Availability Impact | Low |
Impact
Full administrative access to AdGuard Home in a GL.iNet router deployment means control over the network's primary DNS resolver. An attacker can redirect DNS queries to malicious servers, modify blocklists to allow malicious domains, alter DHCP configurations, and silently surveil all DNS traffic. DNS level manipulation is particularly insidious because it is difficult to detect without dedicated monitoring infrastructure, which is rarely present in the home and small office environments where GL.iNet routers are deployed.
Discovery
The vulnerability was discovered by security researcher djnn (GitHub: @djnnvx) and coordinated through VulnCheck, which served as the CVE Numbering Authority.
Patch Information
AdGuard Home v0.107.77, released June 2, 2026, addresses CVE-2026-41448 with a well structured fix that eliminates the path traversal vector at the filesystem API level rather than relying on input sanitization. The changes are visible in the diff between v0.107.76 and v0.107.77.
Eliminating the Mutable Path Prefix
The first change converts the token file prefix from a mutable variable containing a full filesystem path to a constant containing only the filename prefix:
// BEFORE (internal/home/authglinet.go) var glFilePrefix = "/tmp/gl_token_" // AFTER (internal/home/authglinet.go) const glFilePrefix = "gl_token_"
This strips the directory component entirely, removing the ability for the prefix itself to be manipulated and ensuring the filename portion is a compile time constant.
Introducing os.Root for Directory Confinement
The patch replaces the tokenFilePrefix string configuration field with a tokenFileRoot *os.Root field. This uses Go 1.24's os.OpenRoot facility, which creates a handle to a directory that cannot be escaped via path traversal. The root is opened at startup:
if opts.glinetMode { glTokenFileRoot, err = os.OpenRoot("/tmp/") fatalOnError(err) }
This *os.Root value is threaded through the configuration structs (authConfig, authMiddlewareGLiNetConfig) into the middleware.
Replacing os.Open with Sandboxed Open
The critical change is in the tokenDate method where the token file is actually opened:
// BEFORE f, err := os.Open(tokenFile) // AFTER f, err := mw.tokenFileRoot.Open(tokenFile)
os.Root.Open() resolves paths relative to the root directory and rejects any traversal sequences. A cookie value like /../../etc/passwd will no longer escape the /tmp/ sandbox.
Test Coverage
The patch adds explicit test cases that attempt path traversal and verify it fails:
reqPathTraversalToken := httptest.NewRequest(http.MethodGet, "/", nil) reqPathTraversalToken.AddCookie(&http.Cookie{ Name: glCookieName, Value: "/../../path_traversal_token", })
The test asserts that this request results in an HTTP 302 redirect to the login page, confirming the traversal is blocked.
This is a textbook example of defense in depth: rather than attempting to sanitize the input (which is error prone), the fix confines the filesystem operation to a specific directory at the OS level, making traversal structurally impossible.
Affected Systems and Versions
All versions of AdGuard Home prior to v0.107.77 are affected when running with the --glinet command line flag. Specifically:
- Affected: AdGuard Home versions before 0.107.77 launched with
--glinet - Not affected: AdGuard Home instances running without the
--glinetflag (standard deployments) - Fixed in: AdGuard Home v0.107.77 (released June 2, 2026)
The --glinet flag is the default integration mode on all GL.iNet router models that bundle AdGuard Home, including but not limited to:
- GL.iNet Flint 3 (GL-BE9300)
- GL.iNet Beryl 7 (GL-MT3600BE)
- GL.iNet Slate 7 (GL-BE3600)
GL.iNet router firmware updates lag behind upstream AdGuard Home releases. Even after AdGuard Home v0.107.77 was released, GL.iNet users may remain exposed until a firmware update incorporating the patched version is issued. The GL.iNet forum has an active thread discussing this update lag, with users asking when patches would be incorporated into firmware.
Vendor Security History
CVE-2026-41448 is the second critical authentication bypass in AdGuard Home in 2026. The first, CVE-2026-32136 (CVSS 9.8), was disclosed in March 2026 and fixed in v0.107.73. That vulnerability exploited the HTTP/2 Cleartext (h2c) upgrade mechanism: the authentication wrapper only applied to the initial HTTP/1.1 upgrade request, leaving h2c connections unauthenticated and able to access admin endpoints. GL.iNet forum staff published a proof of concept for that flaw.
| Attribute | CVE-2026-32136 | CVE-2026-41448 |
|---|---|---|
| CVSS Score | 9.8 | 9.4 / 9.2 (v4) |
| CWE | Auth bypass via protocol | CWE-22 (Path Traversal) |
| Attack Vector | HTTP/2 h2c upgrade | Path traversal in Admin-Token cookie |
| Affected Mode | All deployments | --glinet flag only |
| Fixed Version | v0.107.73 | v0.107.77 |
AdGuard Home has accumulated at least 8 documented CVEs according to OpenCVE. Earlier vulnerabilities CVE-2022-30580 and CVE-2022-29804 were addressed in a release that also introduced enforced password protection. A security bulletin covering five vulnerabilities was issued in March 2024.
The two critical authentication bypasses within three months share a common pattern: the authentication middleware has multiple independent logic paths, and flaws in any single path result in complete bypass. CVE-2026-32136 exploited a protocol level weakness; CVE-2026-41448 exploits a classic input validation failure. Both achieve the same outcome through entirely different mechanisms, indicating that the authentication layer has multiple independent failure modes. This suggests a need for a comprehensive authentication architecture review rather than continued point fixes.
References
- NVD: CVE-2026-41448
- VulnCheck Advisory: AdGuard Home Authentication Bypass via Path Traversal in Admin-Token Cookie
- AdGuard Home v0.107.77 Release Notes
- GitHub Diff: v0.107.76 to v0.107.77
- CVE-2026-41448 on Vulners
- Cloudron Forum: AdGuard Home Package Updates
- CWE-22: Improper Limitation of a Pathname to a Restricted Directory
- NVD: CVE-2026-32136
- GHSA-5fg6-wrq4-w5gh: HTTP/2 Cleartext (h2c) Upgrade Authentication Bypass
- GL.iNet Forum: AdGuard Home Security Update
- OpenCVE: AdGuard Vulnerabilities
- GL.iNet Router Docs: AdGuard Home
- GitHub Issue #1853: GL.iNet Integration
- BeyondMachines: AdGuard Home Patches Critical Authentication Bypass
- SecurityOnline: Critical 9.8 CVSS Flaw in AdGuard Home



