CVEReports
CVEReports

Automated vulnerability intelligence platform. Comprehensive reports for high-severity CVEs generated by AI.

Product

  • Home
  • Sitemap
  • RSS Feed

Company

  • About
  • Contact
  • Privacy Policy
  • Terms of Service

© 2026 CVEReports. All rights reserved.

Made with love by Amit Schendel & Alon Barad



CVE-2026-1529

Keycloak Unlocked: Bypassing Org Security with CVE-2026-1529

Alon Barad
Alon Barad
Software Engineer

Feb 17, 2026·6 min read·303 visits

Executive Summary (TL;DR)

Keycloak forgot to verify JWT signatures in the organization invitation flow. Attackers can take a valid invite token, change the organization ID in the payload to whatever they want, and self-register into restricted organizations without a valid key. It's a high-severity bypass (CVSS 8.1) affecting versions prior to late January 2026.

A critical lapse in cryptographic hygiene within Keycloak's 'Organizations' feature allows attackers to forge invitation tokens. By neglecting to verify the digital signature of JSON Web Tokens (JWTs), Keycloak inadvertently permitted anyone with a valid invite to modify the payload—swapping organization IDs and email addresses—to gain unauthorized access to restricted tenants.

The Hook: Trust, But Don't Verify

Keycloak is the behemoth of the open-source Identity and Access Management (IAM) world. It’s the gatekeeper we trust to hold the keys to the kingdom, handling everything from OAuth flows to user federation. Recently, Keycloak introduced a shiny new feature called Organizations, designed to support multi-tenancy and B2B SaaS scenarios. It allows admins to invite users to specific organizations via email links containing a token.

But here's the kicker: for a brief, terrifying window in versions 26.x, the gatekeeper stopped checking IDs. When processing these invitation tokens, the system assumed that if a token looked like a JWT, it must be valid. It didn't bother checking the cryptographic signature—the wax seal that proves the letter wasn't tampered with.

This isn't just a minor bug; it's a fundamental breakdown of the JWT trust model. In the security world, we call this "signature exclusion" or "algorithm confusion's" dumber cousin: simply ignoring the signature entirely. It turned Keycloak's robust security model into a purely advisory suggestion, allowing anyone with a text editor to rewrite their own access permissions.

The Flaw: A Failure of Logic

To understand why this is hilarious (in a dark way), you have to understand how Keycloak handles tokens. Usually, the code is paranoid. It checks expiration, issuers, audiences, and crucially, the cryptographic signature using the realm's public key. If a single bit is out of place, the token is rejected.

However, in the org.keycloak.organization.utils.Organizations class, the developers got a little lazy—or perhaps just distracted. The method parseInvitationToken was tasked with reading the token from the URL query parameters. Instead of invoking the full verification pipeline, the code simply deserialized the Base64-encoded payload directly into a Java object.

It’s the digital equivalent of a bouncer looking at a driver's license, seeing that it's a rectangular piece of plastic with a photo, and letting you in—without noticing that the name is written in Crayon and the birth year is 3025. Because the signature verification step (verifier.verify()) was completely omitted, the server accepted any JSON blob formatted as a token, regardless of who signed it (or if it was signed at all).

The Code: The Smoking Gun

Let's look at the crime scene. The vulnerable code resided in org.keycloak.organization.utils.Organizations.java. Here is the logic that essentially rolled out the red carpet for attackers:

// THE VULNERABLE CODE
public static InviteOrgActionToken parseInvitationToken(HttpRequest request) throws VerificationException {
    // ... query param extraction ...
    String tokenFromQuery = queryParameters.getFirst(Constants.TOKEN);
 
    // LOOK HERE: create() parses the text, getToken() returns the object.
    // There is NO .verify() call. There is NO signature check.
    return TokenVerifier.create(tokenFromQuery, InviteOrgActionToken.class).getToken();
}

The fix, introduced in commit 8fc9a98026106a326f4faa98d4c9a48341ace2d7, is a lesson in how verbose Java security can get. They had to wire in the KeycloakSession, fetch the SignatureVerifierContext, and explicitly force the check:

// THE PATCHED CODE
public static InviteOrgActionToken parseInvitationToken(KeycloakSession session, HttpRequest request) throws VerificationException {
    // ... setup ...
    TokenVerifier<InviteOrgActionToken> verifier = TokenVerifier.create(tokenFromQuery, InviteOrgActionToken.class)
            .withChecks(TokenVerifier.IS_ACTIVE, /* URL checks */);
 
    // Fetch the realm's keys to verify the signature
    SignatureVerifierContext verifierContext = session.getProvider(SignatureProvider.class, 
            verifier.getHeader().getAlgorithm().name())
            .verifier(verifier.getHeader().getKeyId());
 
    verifier.verifierContext(verifierContext);
    
    // The magic word: .verify()
    return verifier.verify().getToken(); 
}

The difference is subtle in lines of code but infinite in security implications. The first version trusts the input; the second version treats the input like a hostile combatant until proven otherwise.

The Exploit: Forging Your Way In

Exploiting this requires zero advanced hacking tools. You don't need heap spraying or ROP chains; you just need a browser developer console or a simple Python script. The attack vector relies on the fact that a JWT is just Header.Payload.Signature. Since the server ignores the Signature, we can change the Payload and leave the Signature as garbage (or keep the original, it doesn't matter).

Step 1: The Setup. The attacker needs a valid invitation link. They can invite themselves to a "dummy" organization they control to get a valid token format. The link looks like https://auth.target.com/realms/main/protocol/openid-connect/registrations?token=eyJhbG...

Step 2: The Tampering. The attacker takes the token string. The middle part (between the two periods) is the Base64-encoded payload. They decode it and see JSON:

{
  "iss": "https://auth.target.com/realms/main",
  "orgId": "b-123-useless-org",
  "email": "attacker@evil.com",
  "exp": 1790000000
}

They change "orgId" to the ID of the Executive Org (e.g., "a-999-super-secret-admin-org") which they might have enumerated via other API leaks or guessed. They ensure the email matches the account they want to register.

Step 3: The Delivery. The attacker re-encodes this JSON to Base64 and pastes it back into the token string. They send the request. Keycloak's parseInvitationToken method deserializes the forged payload, sees the target orgId, assumes it's valid because it deserialized correctly, and grants the attacker membership to the target organization. Congratulations, you are now an employee.

The Impact: Breaking Tenant Isolation

The impact here is a complete violation of multi-tenancy. In a SaaS platform using Keycloak Organizations, this vulnerability allows cross-tenant access. An attacker can move laterally from a low-value demo organization into a high-value corporate organization simply by knowing the target's ID.

Depending on how the application consumes these organizational memberships, this could lead to:

  1. Data Exfiltration: Accessing shared documents, proprietary data, or user lists belonging to the victim organization.
  2. Privilege Escalation: If the invitation flow assigns default roles (like 'Member' or 'Admin') automatically, the attacker gains those privileges immediately upon registration.
  3. Social Engineering: Once inside the org, the attacker looks like a legitimate user, making phishing attacks against other employees significantly more effective.

This scores an 8.1 on CVSS not because it crashes the server, but because it destroys the integrity of the access control model. Confidentiality and Integrity are both rated 'High' for a reason.

The Fix: Patch or Die

Red Hat and the Keycloak maintainers pushed a fix in late January 2026. The remediation is straightforward: Update Keycloak immediately.

If you are running Keycloak version 26.2.x, upgrade to 26.2.13-1 or later. If you are running version 26.4.x, upgrade to 26.4.9-1 or later.

If patching is currently impossible due to bureaucratic inertia or change freezes, there is a configuration workaround: Disable the Organizations feature. This feature is often guarded by a feature flag. Turning it off removes the vulnerable endpoint entirely. However, if your business logic relies on this feature, you are effectively stuck between a rock and a hard place until you patch.

Official Patches

Red HatRHSA-2026:2363 - Keycloak Security Update
KeycloakOfficial GitHub Commit

Fix Analysis (1)

Technical Appendix

CVSS Score
8.1/ 10
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N
EPSS Probability
0.02%
Top 97% most exploited

Affected Systems

Keycloak 26.2.x prior to 26.2.13-1Keycloak 26.4.x prior to 26.4.9-1Red Hat build of Keycloak (RHBK)

Affected Versions Detail

Product
Affected Versions
Fixed Version
Keycloak
Red Hat
26.2.0 - 26.2.1226.2.13-1
Keycloak
Red Hat
26.4.0 - 26.4.826.4.9-1
AttributeDetail
CWE IDCWE-347 (Improper Verification of Cryptographic Signature)
CVSS v3.18.1 (High)
Attack VectorNetwork (AV:N)
Privileges RequiredLow (PR:L)
Exploit StatusPoC Available
EPSS Score0.00016 (Rising)
ImpactHigh Integrity & Confidentiality Loss

MITRE ATT&CK Mapping

T1566Phishing
Initial Access
T1098Account Manipulation
Persistence
T1078Valid Accounts
Defense Evasion
CWE-347
Improper Verification of Cryptographic Signature

The product does not verify, or incorrectly verifies, the cryptographic signature for data, allowing the data to be modified without detection.

Known Exploits & Detection

GitHubPython script for modifying JWT claims in Keycloak invitation tokens
GitHubRegistration endpoint bypass tool
NucleiDetection Template Available

Vulnerability Timeline

Fix committed by Stian Thorgersen
2026-01-29
Public disclosure and Red Hat Security Advisories published
2026-02-09
First PoC released on GitHub
2026-02-12

References & Sources

  • [1]Red Hat CVE Database
  • [2]Bugzilla Report #2433783

Attack Flow Diagram

Press enter or space to select a node. You can then use the arrow keys to move the node around. Press delete to remove it and escape to cancel.
Press enter or space to select an edge. You can then press delete to remove it or escape to cancel.

More Reports

•about 1 hour ago•CVE-2026-58197
8.8

CVE-2026-58197: Host Escape and Lateral Movement via Insecure Container Network Defaults in ToolHive

A high-severity access control vulnerability in ToolHive CLI before v0.30.1 and ToolHive Studio before v0.38.0 allows local containerized MCP servers to bypass network isolation. This enables malicious workloads to establish TCP/IP connections to administrative and control plane endpoints exposed on the host loopback interface.

Amit Schendel
Amit Schendel
3 views•8 min read
•about 2 hours ago•CVE-2026-63405
5.9

CVE-2026-63405: Insufficient Verification of Data Authenticity in AnyCable Pusher REST API

AnyCable is a real-time communication server. Prior to version 1.6.15, its Pusher-compatible REST API suffered from an authentication bypass vulnerability because it failed to verify that the request body matched the signature-validated body_md5 parameter. This allows attackers to perform replay attacks with modified body contents.

Amit Schendel
Amit Schendel
3 views•5 min read
•about 3 hours ago•CVE-2026-64847
6.8

CVE-2026-64847: Indefinite Denial of Service via Undrained Stderr in AnyIO Process Pool Workers

A denial-of-service vulnerability exists in AnyIO prior to version 4.14.2. Standard error streams of process-pool workers are connected to an operating system pipe that is never drained by the parent process. This allows a worker to fill the pipe buffer and deadlock indefinitely.

Amit Schendel
Amit Schendel
5 views•6 min read
•about 4 hours ago•CVE-2026-63349
7.0

CVE-2026-63349: Privilege Dropping Bypass and Denial of Service in AnyIO Subprocess Module

CVE-2026-63349 is a critical privilege-dropping bypass vulnerability in the AnyIO asynchronous framework (versions 4.14.0 and 4.14.1) on POSIX platforms. Due to a variable assignment typo, supplementary groups specified by the developer are not correctly propagated to the execution backend, resulting in subprocesses retaining the parent process's elevated supplementary group permissions.

Alon Barad
Alon Barad
7 views•5 min read
•about 5 hours ago•CVE-2026-63406
5.9

CVE-2026-63406: Information Disclosure via Insecure Telemetry and Hardcoded Credentials in AnyCable-Go

CVE-2026-63406 is an information disclosure vulnerability in AnyCable-go prior to version 1.6.15. The built-in telemetry client is enabled by default with a hardcoded public authentication token ('secret'). This client digests highly sensitive configuration parameters and command-line arguments, including JWT secrets and RPC secrets, into a stable SHA-256 fingerprint. This fingerprint is sent over public networks, exposing those administrative secrets to offline dictionary and brute-force attacks if intercepted.

Alon Barad
Alon Barad
5 views•5 min read
•about 6 hours ago•CVE-2026-84992
6.1

CVE-2026-84992: Cross-Site Scripting (XSS) via Fenced Code Block Parsing in md-editor-v3

CVE-2026-84992 is a Cross-Site Scripting (XSS) vulnerability affecting md-editor-v3 before version 6.5.4. It occurs because the fenced-code block language parser directly interpolates unescaped language metadata into unquoted HTML attributes inside the custom rendering callback. This bypasses the built-in XSSPlugin which runs during the parsing phase, before rendering.

Amit Schendel
Amit Schendel
8 views•6 min read