Summary
Arcane: Environment access token bypasses the admin-required authorization gate on /api/debug/pprof
Arcane v2.10.2 contains an authorization inconsistency in AuthMiddleware.managerAuth.
When a request supplies a valid environment access token through the X-Arcane-Agent-Token header, managerAuth resolves the associated environment, installs an environment-scoped permission set, and immediately calls next(c).
This occurs before the middleware evaluates the AdminRequired option and verifies that the caller is a global administrator.
As a result, an environment-scoped access token can access routes protected with WithAdminRequired(), despite the corresponding EnvironmentPermissionSet intentionally containing no global or sudo permissions.
In v2.10.2, the affected admin-only surface is the manager's Go pprof diagnostic interface under:
/api/debug/pprof/*
This exposes diagnostic and runtime profiling information that the application explicitly intends to restrict to global administrators.
The issue is an incorrect authorization vulnerability (CWE-863).
Details
1. Environment access tokens are accepted by the manager authentication middleware
The production authentication middleware is configured with an environment access-token resolver:
backend/internal/di/providers.go
Conceptually, the middleware is constructed as:
auth.NewAuthMiddleware(authService, cfg).
WithApiKeyValidator(apiKey).
WithEnvironmentAccessTokenResolver(env).
WithPermissionResolver(role)
Therefore, the X-Arcane-Agent-Token authentication path is active in the production manager.
2. The environment-token path returns before authorization options are evaluated
The relevant logic is in:
backend/internal/auth/middleware.go
managerAuth first checks the X-Arcane-Agent-Token header.
When the token resolves to an environment, the middleware installs an environment-scoped permission set and immediately continues processing:
if agentToken := req.Header.Get(utils.HeaderAgentToken); agentToken != "" {
if env, ok := m.resolveEnvironmentAccessToken(ctx, agentToken).Get(); ok {
environmentScopedInternal(c, env)
return next(c)
}
}
The important part is the unconditional:
return next(c)
The normal authentication path later evaluates the middleware's AdminRequired option:
ps := m.resolvePermissionsOrDeny(ctx, user)
if m.options.AdminRequired && !ps.IsGlobalAdmin() {
return c.JSON(http.StatusForbidden, common.APIError{
Code: "FORBIDDEN",
Message: "You don't have permission to access this resource",
})
}
The environment-token branch never reaches this check.
Consequently, WithAdminRequired() has no effect when authentication succeeds through a valid environment access token.
This creates an authorization inconsistency between authentication mechanisms:
normal user/session authentication →
AdminRequiredis enforced;environment access-token authentication →
AdminRequiredis bypassed.
3. Environment tokens are intentionally not global-administrator credentials
backend/pkg/authz/permission_set.go defines the effective permissions assigned to an environment access token.
EnvironmentPermissionSet(envID) grants environment-scoped permissions only for the specified environment:
func EnvironmentPermissionSet(envID string) *PermissionSet {
ps := NewPermissionSet()
if envID == "" {
return ps
}
for _, p := range AllPermissions() {
if IsEnvScoped(p) {
ps.AddEnv(envID, p)
}
}
return ps
}
The implementation explicitly establishes that these credentials do not receive global or sudo permissions.
Therefore, an environment access token should not satisfy a global-administrator authorization requirement.
The early return in managerAuth bypasses this intended privilege boundary.
4. /api/debug/pprof/* explicitly requires global-administrator authorization
The diagnostic routes are registered in:
backend/api/ws/diagnostics.go
The pprof group is protected using:
pprofGroup := group.Group(
"/debug/pprof",
authMiddleware.WithAdminRequired().Add(),
)
The source also documents the intended authorization requirement by noting that pprof keeps the stricter admin-required gate.
The group exposes handlers including:
/api/debug/pprof/
/api/debug/pprof/cmdline
/api/debug/pprof/profile
/api/debug/pprof/symbol
/api/debug/pprof/trace
/api/debug/pprof/heap
/api/debug/pprof/goroutine
/api/debug/pprof/allocs
/api/debug/pprof/block
/api/debug/pprof/mutex
/api/debug/pprof/threadcreate
Named profiles are dispatched through pprof.Handler.
Because WithAdminRequired() is bypassed by the environment-token branch, a valid environment access token can reach these handlers even though its permission set is not globally privileged.
5. Other middleware does not restore the missing authorization check
The CSRF middleware recognizes X-Arcane-Agent-Token as a header-based credential and does not apply the normal cross-origin CSRF validation to such requests.
Additionally, the environment proxy middleware passes through requests that do not target an /environments/{id}/... path.
Therefore a request to:
/api/debug/pprof/*
can proceed to managerAuth, enter the environment-token authentication branch, and reach the pprof handler without another global-administrator authorization check being applied.
Source-to-sink authorization path
The vulnerable control flow is:
X-Arcane-Agent-Token
|
v
environment access token resolver
|
v
environment resolved successfully
|
v
EnvironmentPermissionSet(environmentID)
|
v
return next(c)
|
| AdminRequired check is skipped
v
/api/debug/pprof/*
|
v
net/http/pprof handler
The security boundary violation occurs at the early return next(c).
Proof of Concept
Preconditions
The test requires:
A valid Arcane environment access token.
An Arcane manager running the affected code.
No global-administrator account or credentials.
Test 1, environment access token
Send a request to an admin-protected pprof endpoint using only an environment access token:
GET /api/debug/pprof/heap?debug=1 HTTP/1.1
Host: arcane.example.com
X-Arcane-Agent-Token: <VALID_ENVIRONMENT_ACCESS_TOKEN>
No administrator session cookie or administrator Bearer token is supplied.
Vulnerable behavior
On an affected instance, the request is expected to reach the pprof handler instead of being rejected by WithAdminRequired().
A successful response demonstrates that the environment-token authentication branch bypasses the administrator requirement.
For example, the response may contain the Go heap profiling output generated by net/http/pprof.
Test 2, non-admin user contrast case
Send the same request using a normal authenticated non-global-admin user:
GET /api/debug/pprof/heap?debug=1 HTTP/1.1
Host: arcane.example.com
Authorization: Bearer <NON_ADMIN_ACCESS_TOKEN>
The expected result is:
HTTP/1.1 403 Forbidden
with an authorization error indicating that the user does not have permission to access the resource.
This contrast demonstrates the authorization inconsistency:
environment-scoped token
-> admin gate skipped
-> pprof handler reached
normal non-admin user
-> admin gate evaluated
-> HTTP 403
Expected secure behavior
A valid environment access token should receive:
HTTP/1.1 403 Forbidden
for every route protected with WithAdminRequired().
Only a caller whose effective permission set satisfies IsGlobalAdmin() should be allowed to access these routes.
Root Cause
The root cause is that authentication through an environment access token takes an early-success path:
environmentScopedInternal(c, env)
return next(c)
before common middleware authorization options are evaluated.
As a result, authorization requirements configured on the middleware are dependent on which authentication mechanism is used.
Authentication establishes the identity and scope of the caller, but route-level authorization requirements such as AdminRequired should subsequently be applied consistently regardless of the authentication mechanism.
Regression Tests
The following cases should be covered:
Valid environment access token
+ /api/debug/pprof/heap
=> 403
Normal authenticated non-admin user
+ /api/debug/pprof/hea
=> 403
Unauthenticated request
+ /api/debug/pprof/heap
=> 401/403
Global administrator
+ /api/debug/pprof/heap
=> 200
More generally, tests should verify that every authentication mechanism is subject to middleware options such as AdminRequired.
The issue could also broadly be categorized as an authorization-check bypass caused by inconsistent authorization handling across authentication paths..
No claim of credential extraction, arbitrary process-memory disclosure, or global-administrator takeover is made unless separately demonstrated through dynamic testing.
Impact
An attacker who obtains a valid environment access token can cross the intended authorization boundary between an individual environment and manager-wide administrative functionality.
In the currently identified route configuration, this allows unauthorized access to the manager's Go pprof diagnostic endpoints.
Depending on the requested profile, these endpoints can expose internal runtime and diagnostic information such as:
goroutine stack traces;
function and package names;
allocation and heap profiling information;
CPU profiling information;
runtime execution traces;
process command-line information;
mutex, block, thread and allocation profiling data.
This information is normally restricted to global administrators by Arcane's explicit use of WithAdminRequired().
Some profiling operations may also impose additional CPU, memory, or tracing overhead while being collected.
Importantly, this report does not assume that Go's pprof heap endpoint is an arbitrary raw-process-memory dump. Direct extraction of session tokens, environment access tokens, passwords, or other credentials from pprof output has not been demonstrated and is therefore not claimed as part of the confirmed impact.
The confirmed security issue is the authorization bypass itself and the resulting unauthorized exposure of administrator-restricted diagnostic functionality.
The application does not correctly enforce access controls, allowing a principal to access resources or operations beyond their granted permissions. Typical impact: unauthorized data access or execution of privileged operations.
CVE-2026-96628 has a CVSS score of 4.3 (Medium). The vector is network-reachable, low privileges required, and no user interaction. A CVSS score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether this affects your application depends on whether the vulnerable code is present and reachable in your environment. A fixed version is available (2.11.0); upgrading removes the vulnerable code path.
Affected versions
Security releases
Kodem intelligence
Severity tells you how bad this could be in the worst case. It does not tell you whether you are exposed. Exploitability and impact are functions of runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A vulnerable package can sit in your dependency tree and never run.
Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter. Kodem's runtime-powered SCA identifies whether this CVE is reachable in your applications.
Already deployed Kodem?
See it in your environmentNew to Kodem? Get a demo →Remediation advice
The environment-token authentication path should not call next(c) before the configured authorization requirements have been evaluated.
One approach is to resolve the environment token into its EnvironmentPermissionSet and then pass that permission set through the same authorization-option evaluation used by other authentication mechanisms.
For example, logically:
if envTokenIsValid {
ps := authz.EnvironmentPermissionSet(env.ID)
if m.options.AdminRequired && !ps.IsGlobalAdmin() {
return forbidden
}
environmentScopedInternal(c, env)
return next(c)
}
Because an EnvironmentPermissionSet intentionally has no global permissions, an environment token would then correctly receive HTTP 403 for WithAdminRequired() routes.
As additional defense in depth, the pprof endpoints could explicitly reject environment access tokens and other environment-scoped authentication mechanisms, allowing access only through authentication mechanisms capable of representing a global administrator.
It may also be worth considering whether pprof should be exposed in production by default or enabled only through an explicit diagnostic configuration option.
Frequently Asked Questions
- What is CVE-2026-96628? CVE-2026-96628 is a medium-severity incorrect authorization vulnerability in github.com/getarcaneapp/arcane/backend/v2 (go), affecting versions < 2.11.0. It is fixed in 2.11.0. The application does not correctly enforce access controls, allowing a principal to access resources or operations beyond their granted permissions.
- How severe is CVE-2026-96628? CVE-2026-96628 has a CVSS score of 4.3 (Medium). This score reflects the worst-case severity of the vulnerability, not your specific exposure. Whether it represents real risk in your environment depends on whether the vulnerable code is present and reachable.
- Which versions of github.com/getarcaneapp/arcane/backend/v2 are affected by CVE-2026-96628? github.com/getarcaneapp/arcane/backend/v2 (go) versions < 2.11.0 is affected.
- Is there a fix for CVE-2026-96628? Yes. CVE-2026-96628 is fixed in 2.11.0. Upgrade to this version or later.
- Is CVE-2026-96628 exploitable, and should I be worried? Whether CVE-2026-96628 is exploitable in your environment depends on whether the vulnerable code is present and reachable. A CVSS score is a worst-case rating; it does not account for your specific deployment, configuration, or usage patterns. Kodem, an Intelligent Application Security platform, uses runtime intelligence to show which vulnerabilities actually execute in production, so you can focus on the ones that represent real risk. Get a demo
- What actually determines whether CVE-2026-96628 is exploitable, and how bad it is? Exploitability and impact are not fixed properties of a CVE. They depend on runtime truth: whether the vulnerable code is present, reachable, and actually executes in your application. A high CVSS score on a dependency that never runs is not the same as real risk. Kodem, an Intelligent Application Security platform, uses runtime intelligence to reveal which vulnerabilities actually execute in production, so teams prioritize the ones that genuinely matter.
- How do I fix CVE-2026-96628? Upgrade
github.com/getarcaneapp/arcane/backend/v2to 2.11.0 or later.