Aug 29, 2026·7 min read·43 visits
An authenticated attacker with low privileges can revoke any user's access tokens via an IDOR vulnerability in Graylog's token removal API endpoint.
An Insecure Direct Object Reference (IDOR) vulnerability exists within the access-token revocation endpoint of Graylog. Authenticated users can exploit this flaw to delete access tokens belonging to other users, including high-privileged administrator accounts, thereby disrupting active integrations and API access.
The graylog2-server component of Graylog contains an Insecure Direct Object Reference (IDOR) vulnerability in its REST API interface. The security flaw is located within the access-token revocation mechanism, which is managed by the UsersResource class. Under normal operations, users should only be authorized to generate, view, and destroy access tokens that are assigned to their own accounts.
The vulnerability allows an authenticated attacker to bypass authorization boundaries and revoke active tokens belonging to arbitrary users. This behavior is possible because the endpoint processes requests based on attacker-controlled inputs without performing relational validation between the token owner and the requesting entity. The primary impact is the unauthorized modification of system state, leading to a localized disruption of services.
This flaw poses a risk to environments where automated services, ingestion pipelines, and administrative workflows rely on static access tokens. Unplanned token revocation can invalidate automated sessions and disrupt logs processing across the enterprise network. Understanding the technical mechanics of this endpoint is necessary to mitigate the risks associated with this vulnerability.
The root cause of CVE-2026-55867 lies in the logical implementation of the revokeToken method inside the UsersResource controller. This endpoint accepts two primary path parameters: userId and idOrToken. During API processing, the application relies on the userId parameter to retrieve the associated user record and perform a permission check.
The controller verifies if the calling session is permitted to perform the USERS_TOKENREMOVE action on the user retrieved via userId. If a low-privileged attacker provides their own user identifier as the userId, the authorization routine evaluates this action as legitimate and permits the request to proceed. This creates a logical flaw where authorization is granted based on one input while the state-changing operation is performed on another.
Following the successful authorization check, the method queries the database using the second parameter, idOrToken, to fetch the actual AccessToken object. The application fails to verify whether the retrieved token actually belongs to the user validated in the first step. The system executes the deletion command accessTokenService.destroy(accessToken) directly, thereby allowing the deletion of any token whose ID is known.
To understand the vulnerability, it is necessary to examine the vulnerable Java code implementation alongside the patched version. The vulnerable implementation retrieves the user based on the path parameter before performing the permission check, and then separately retrieves the access token.
// Vulnerable Code Implementation
public void revokeToken(
@Parameter(name = "userId", required = true) @PathParam("userId") String userId,
@Parameter(name = "idOrToken", required = true) @PathParam("idOrToken") String idOrToken) {
// The application checks authorization using the client-supplied 'userId'
final User user = loadUserById(userId);
final String username = user.getName();
if (!isPermitted(USERS_TOKENREMOVE, username)) {
throw new ForbiddenException("Not allowed to remove tokens for user " + username);
}
// The application retrieves the token directly, without checking ownership
final AccessToken accessToken = Optional.ofNullable(accessTokenService.loadById(idOrToken))
.orElse(accessTokenService.load(idOrToken));
if (accessToken != null) {
// The token is destroyed regardless of who owns it
accessTokenService.destroy(accessToken);
} else {
throw new NotFoundException("Couldn't find access token for user " + username);
}
}The patch resolved this issue by refactoring the verification logic to depend entirely on the retrieved token object instead of the user-supplied parameter. The userId parameter is left in the function signature only to maintain backwards compatibility with existing clients, but it is no longer used during validation.
// Patched Code Implementation
public void revokeToken(
@Parameter(name = "userId", required = true) @PathParam("userId") String userId,
@Parameter(name = "idOrToken", required = true) @PathParam("idOrToken") String idOrToken) {
// The token is loaded first using the 'idOrToken' path parameter
final AccessToken accessToken = Optional.ofNullable(accessTokenService.loadById(idOrToken))
.orElseGet(() -> accessTokenService.load(idOrToken));
if (accessToken == null) {
// The error message is generic to prevent username enumeration or leakage
throw new NotFoundException("Couldn't find access token for user.");
}
// Authorization is evaluated against the actual owner of the retrieved token
if (!isPermitted(USERS_TOKENREMOVE, accessToken.getUserName())) {
throw new ForbiddenException("Not allowed to remove token for user " + accessToken.getUserName());
}
// State destruction is performed only after a successful authorization check
accessTokenService.destroy(accessToken);
}This refactoring represents a complete fix because it couples the authorization context to the target database record. Because the code retrieves the token first and extracts its actual owner's username directly from the persistent storage, an attacker cannot manipulate the validation context. There are no known bypasses or variant attack paths targeting this specific controller logic post-patch.
Exploitation of CVE-2026-55867 requires a low-privilege authenticated account on the Graylog server. The attacker must also possess or acquire the target token's unique identifier or the token value itself. Because token values are often represented as database-assigned UUIDs, the attack is highly feasible if token IDs are leaked through other endpoints, log files, or session states.
An attacker initiates the attack by crafting a malicious HTTP DELETE request. The attacker sets the userId segment of the URI path to their own valid user identifier, which satisfies the server's initial checks. The target token's ID is placed in the idOrToken segment of the path, pointing the application to the resource scheduled for destruction.
DELETE /api/users/attacker_user_id/tokens/victim_token_id HTTP/1.1
Host: graylog.example.com
Authorization: Basic YXR0YWNrZXI6cGFzc3dvcmQ=
Accept: application/jsonUpon receiving this request, the server executes the vulnerable code path, validating the attacker's permissions on their own account and then deleting the victim's token. The server returns an HTTP 204 No Content or 200 OK response, indicating a successful deletion. The target token is immediately invalidated in the database, terminating any active sessions or integrations utilizing that token.
The security impact of CVE-2026-55867 is categorized primarily as an integrity and availability concern. Although the vulnerability does not allow an attacker to view the contents of other users' tokens or read sensitive data, unauthorized deletion of credentials represents a significant operational risk.
If an attacker targets tokens used by administrators or high-privilege service integrations, they can disrupt critical workflows. Automated ingestion pipelines, log collectors, alert forwarders, and SIEM integrations that rely on persistent access tokens will immediately fail upon token revocation. This results in a localized denial of service and potential visibility gaps in security monitoring.
From an access control perspective, the vulnerability breaks the principle of least privilege by allowing lower-privileged users to modify administrative configurations. However, because the flaw cannot be exploited without authenticating first and does not lead to direct code execution or information disclosure, it is assigned a CVSS base score of 5.3 (Medium).
The recommended remediation path is to upgrade affected Graylog instances to the fixed versions. The vendor has released patches in versions 6.3.12, 7.0.7, and 7.1.2 which properly address the authorization flow. These updates should be scheduled and applied according to standard change management procedures.
> [!NOTE]
> If immediate patching is not possible, security administrators can implement temporary defensive measures. Organizations should monitor Graylog REST API access logs for anomalous DELETE requests targeting /api/users/*/tokens/* where the user ID in the path does not align with the authenticated session's user identity.
Additionally, restricting network access to the Graylog web console and REST API limits the potential attack surface. Limiting API access to trusted administrative workstations and internal networks reduces the likelihood of unauthorized exploitation by untrusted actors.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:N/VI:L/VA:L/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
graylog2-server Graylog | >= 6.2.0, < 6.3.12 | 6.3.12 |
graylog2-server Graylog | >= 7.0.0-alpha.1, < 7.0.7 | 7.0.7 |
graylog2-server Graylog | >= 7.1.0-alpha.1, < 7.1.2 | 7.1.2 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-639 |
| Attack Vector | Network |
| Privileges Required | Low (Authenticated) |
| CVSS v4.0 Score | 5.3 (Medium) |
| Exploit Status | None |
| KEV Status | Not Listed |
The system uses user-controlled keys or identifiers to access resource objects without sufficiently verifying that the authenticated user has authorization to access or modify those objects.
CVE-2026-109619 (PHP2Shell) is a critical Use-After-Free vulnerability in the core PHP engine caused by improper global state cleanup during out-of-memory exception handling across persistent worker requests.
In Python virtualenv prior to version 21.14.9, activation script generators and configuration writers use Path.exists() before writing files. Because Path.exists() resolves symbolic links, it returns False for dangling symlinks. Consequently, virtualenv skips unlinking pre-planted symbolic links or hard links, writing data directly to target locations outside the intended virtual environment directory.
A remote code execution vulnerability exists in Microsoft .NET due to untrusted data deserialization within the PresentationCore component. The flaw stems from implicit auto-conversion flags during clipboard data retrieval operations.
An out-of-bounds write vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio allows unauthenticated remote attackers to execute arbitrary code via crafted pixel-shader bytecode or auto-converted clipboard payloads.
ASP.NET Core contains a thread deadlock vulnerability (CWE-833) that allows an unauthenticated remote attacker to cause a denial of service over the network by exhausting server thread pool resources.
CVE-2026-70035 is a high-severity Remote Code Execution (RCE) vulnerability in Microsoft .NET Framework, .NET runtime, and Visual Studio caused by improper handling during the deserialization of untrusted data (CWE-502). An unauthenticated attacker can execute arbitrary code within the context of the affected process by delivering a crafted serialized payload.