CVE-2026-5430: WSO2 JWT Bypass and Your Keycloak APIs

Guilliano Molaire Guilliano Molaire 13 min read

CVE-2026-5430 is an authentication bypass in WSO2 API Manager and three related WSO2 API management products: a JWT signed with an algorithm the product does not support could get past authentication, which WSO2 says can lead to administrative account takeover. It scores CVSS 10.0, and CISA added it to the Known Exploited Vulnerabilities (KEV) catalog on 24 September 2026. It is not a Keycloak vulnerability, because Keycloak issues tokens and the bug lives in the code that verifies them. If your APIs or gateways accept Keycloak-issued tokens, the fix on your side is the same one this CVE teaches: pin the algorithms you accept, check issuer and audience, and make every verification error reject the request.

Key Takeaways

  • In May 2026, WSO2 published advisory WSO2-2026-5328 for CVE-2026-5430, rated CVSS 10.0 by default and 9.8 for single-tenant deployments.
  • CISA added it to KEV on 24 September 2026, with a federal remediation deadline of 27 September.
  • The public fix shows a verification error that was logged but not turned into a rejection.
  • Resource servers trusting Keycloak should allow-list RS256 (or ES256), check iss and aud, and fail closed.

What is CVE-2026-5430?

WSO2’s own advisory, “Security Advisory WSO2-2026-5328/CVE-2026-5430” (published 3 May 2026), describes it in one sentence: “JWT authentication can be bypassed when a token is signed using an unsupported algorithm, allowing unauthorized access.” The advisory rates it CVSS 3.1 10.0 by default (with a changed scope), adjusted to 9.8 for single-tenant deployments where, in WSO2’s words, the impact is contained within a single security authority boundary.

The affected products and versions, from that advisory, are:

Product Affected versions Fixed update level
WSO2 API Manager 4.1.0 to 4.6.0 4.6.0 U21, 4.5.0 U57, 4.4.0 U72, 4.3.0 U108, 4.2.0 U197, 4.1.0 U257
WSO2 API Control Plane 4.5.0, 4.6.0 4.6.0 U22, 4.5.0 U58
WSO2 Traffic Manager 4.5.0, 4.6.0 4.6.0 U21, 4.5.0 U56
WSO2 Universal Gateway 4.5.0, 4.6.0 4.6.0 U21, 4.5.0 U57

Teams on the open-source builds without a support subscription get the code fix from wso2/carbon-apimgt#13752 (merged 12 April 2026), and the advisory also lists a companion test change, wso2/product-apim#14167 (merged 22 April 2026). WSO2 credits the Hacktron team with reporting it, and the advisory offers no configuration workaround: you patch, update, or move to an unaffected version.

Why is it on the CISA KEV list now?

The patch has been public since April, but exploitation only showed up in September 2026. SecurityWeek reported on 16 September 2026, in “Enterprises Warned of Attacks Exploiting WSO2 Vulnerability”, that watchTowr’s honeypots saw the first attempts on 13 September using forged JWTs that claimed admin privileges. CISA then added the CVE to the KEV catalog on 24 September with a due date of 27 September for US federal agencies.

One detail is worth knowing if you read the KEV entry directly. In the CISA KEV catalog data (catalog version 2026.09.29), the entry’s name reads “WSO2 Multiple Products Path Traversal Vulnerability”, and its short description says the products “contain a path traversal vulnerability that could allow for unrestricted file upload and lead to remote code execution.” The same entry lists CWE-347, Improper Verification of Cryptographic Signature, and links to WSO2’s authentication-bypass advisory, so the text matches neither the vendor’s description nor its own CWE. It looks like a copy error in the catalog rather than a second bug, but until CISA corrects it, the safe reading is to patch as if either description could be true, and the vendor’s update levels are the only fix on offer either way.

Is CVE-2026-5430 a JWT algorithm confusion attack?

Not in the classic sense, although it belongs to the same family of mistakes. In 2020, the IETF’s RFC 8725, “JSON Web Token Best Current Practices”, described the two textbook algorithm attacks in section 2.1: changing the header to "alg": "none" so no signature is checked, and switching RS256 to HS256 so a library uses the RSA public key as an HMAC secret, which lets anyone who has the public key forge tokens. Tim McLean first documented both in 2015 on the Auth0 blog in “Critical vulnerabilities in JSON Web Token libraries”, and they are what most people mean by algorithm confusion.

Neither WSO2 nor CISA says CVE-2026-5430 works that way. What the public fix shows is simpler and in some ways more instructive. In carbon-apimgt pull request #13752, the signature check (JWTUtil.verifyTokenSignature) only handles RS256, RS384 and RS512, and throws an exception for anything else. The authentication interceptor in front of WSO2’s own management REST APIs called that check, caught the exception, logged “Authentication Failure”, and then simply returned, so the request continued down the processing chain instead of being rejected. The fix changes that catch block to throw an error that becomes an HTTP error response. That placement also explains WSO2’s impact statement: the bypass reaches the product’s administrative APIs, which is where account takeover happens.

We have not seen watchTowr’s full exploit write-up, so we would describe this as what the published diff shows, not as confirmed exploit mechanics. The lesson holds either way. A verifier can have a perfectly correct allow-list of algorithms and still be bypassed if an error in the verification path is treated as “log and carry on” rather than “reject”.

Does CVE-2026-5430 affect Keycloak?

No, it does not. Keycloak is the authorization server that signs tokens, and CVE-2026-5430 is a flaw in WSO2 products that verify tokens. Nothing in Keycloak’s token issuance is involved, and there is no Keycloak advisory for it.

The reason it still matters for Keycloak users is that WSO2 API Manager is often deployed alongside Keycloak. WSO2 documents a Keycloak connector for using Keycloak as a third-party key manager, in which Keycloak issues the tokens for your APIs and WSO2 holds the credentials of a Keycloak client it uses to register and manage applications. A well-configured Keycloak realm does not protect the WSO2 admin plane itself, and an attacker who gets admin access there can read what WSO2 stores about your Keycloak setup, including those client credentials. That is the part of this incident that can reach your realm.

The broader lesson applies to any API that verifies tokens itself. Your security depends on both halves: Keycloak issuing tokens correctly, and every resource server (the API that receives the token) checking them correctly. If you want a refresher on how that verification should work end to end, our guide to verifying a Keycloak-issued access token on the backend walks through it step by step.

How should a resource server do JWT signature verification for Keycloak tokens?

RFC 8725 section 3.1, “Perform Algorithm Verification”, says libraries “MUST enable the caller to specify a supported set of algorithms and MUST NOT use any other algorithms when performing cryptographic operations.” In practice that gives you a short checklist for any API that trusts Keycloak tokens:

  1. Allow-list the algorithm explicitly. Keycloak realms sign with RS256 by default. Pass that (or ES256, if you changed the realm’s default signature algorithm) as the only accepted value, and never let the token’s own alg header pick the verification method.
  2. Take keys only from your realm’s JWKS. Fetch keys from https://<host>/realms/<realm>/protocol/openid-connect/certs, select the key by kid, and reject tokens whose kid is not in the set. Our explainer on JWKS and JSON Web Key Sets covers caching and rotation.
  3. Check iss exactly. It should equal https://<host>/realms/<realm>, with no trailing slash differences and no wildcard matching.
  4. Check aud against your API’s own identifier. RFC 8725 section 3.9 asks consumers to use and validate audience, because a valid token minted for a different API should not work on yours.
  5. Check exp and nbf with a small clock skew allowance, usually under a minute.
  6. Fail closed. Any exception during parsing, key lookup or signature checking must end in a 401, never in a log line followed by the next middleware.

The last item is the one CVE-2026-5430 is about, and it is easy to miss because it lives in error handling rather than in the verification call itself.

Node.js with jose

The jose library takes the algorithm list, issuer and audience as options, and jwtVerify throws on any failure:

import { createRemoteJWKSet, jwtVerify } from 'jose';

const issuer = 'https://auth.example.com/realms/acme';
const JWKS = createRemoteJWKSet(new URL(`${issuer}/protocol/openid-connect/certs`));

export async function requireToken(req, res, next) {
  try {
    const token = (req.headers.authorization || '').replace(/^Bearer /, '');
    const { payload } = await jwtVerify(token, JWKS, {
      issuer,
      audience: 'orders-api',
      algorithms: ['RS256'],
    });
    req.auth = payload;
    return next();
  } catch (err) {
    // Every failure path ends here, and every one returns 401.
    return res.status(401).json({ error: 'invalid_token' });
  }
}

Spring Boot resource server

Spring Security’s NimbusJwtDecoder lets you pin the algorithm when you build it, and the default validator checks exp and nbf. Add issuer and audience validators on top:

@Bean
JwtDecoder jwtDecoder() {
    String issuer = "https://auth.example.com/realms/acme";
    NimbusJwtDecoder decoder = NimbusJwtDecoder
        .withJwkSetUri(issuer + "/protocol/openid-connect/certs")
        .jwsAlgorithm(SignatureAlgorithm.RS256)
        .build();

    OAuth2TokenValidator<Jwt> audience = new JwtClaimValidator<List<String>>(
        JwtClaimNames.AUD, aud -> aud != null && aud.contains("orders-api"));
    decoder.setJwtValidator(new DelegatingOAuth2TokenValidator<>(
        JwtValidators.createDefaultWithIssuer(issuer), audience));
    return decoder;
}

Python with PyJWT

PyJWT requires the algorithms argument on decode, which is exactly the protection RFC 8725 asks for:

import jwt
from jwt import PyJWKClient

ISSUER = "https://auth.example.com/realms/acme"
jwks = PyJWKClient(f"{ISSUER}/protocol/openid-connect/certs")

def verify(token: str) -> dict:
    key = jwks.get_signing_key_from_jwt(token).key
    return jwt.decode(
        token,
        key,
        algorithms=["RS256"],
        audience="orders-api",
        issuer=ISSUER,
    )  # raises on any failure; the caller must turn that into a 401

If you want to see what a token actually carries before you write the checks, paste a sample into our JWT Token Analyzer to read its alg, kid, iss and aud, and use the JWKS Verifier to confirm the kid resolves against your realm’s key set.

What should you check in an API gateway’s JWT validation?

A gateway sits in front of many APIs, so a single mistake in its JWT handling has a much larger blast radius than a bug in one service. When you review a gateway’s JWT plugin or policy, whether it is WSO2, Kong, NGINX, Envoy or a cloud API gateway, look for these four things:

  • An explicit algorithm setting. If the configuration has no field for accepted algorithms, find out what the plugin does with an unexpected alg, and test it.
  • Behavior on error. Send a token with "alg": "none", one with "alg": "HS256", one with an unknown kid, and one with a garbage signature. Each should produce a 401 at the gateway, not a 200 or a 500 that still reaches the backend.
  • Issuer and audience checks at the gateway, not only in the backend. Defense in depth only works if both layers are actually checking.
  • Patch cadence. CVE-2026-5430 was fixed in April 2026 and first seen exploited in September 2026, so any deployment running a build from before the fix was exposed for the whole five months in between.

For a broader view of where gateway checks end and service checks begin, see our comparison of token introspection vs local validation and the general API authentication best practices guide.

How do you set up Keycloak so verifier mistakes hurt less?

Keycloak cannot fix a broken verifier, but a few realm settings reduce how much damage one can do. They are all standard Keycloak 26.x settings:

  • Keep one signing algorithm per realm. The realm’s default signature algorithm (in the realm’s token settings) is RS256 unless you change it. Clients can override it per client, and mixed algorithms make allow-lists harder to write, so only override when a client genuinely needs something else.
  • Keep access tokens short-lived. Keycloak’s default access token lifespan is five minutes. A short lifespan limits how long a stolen real token stays useful, although it does nothing against a forged token that a broken verifier accepts.
  • Give every API its own audience. By default many Keycloak access tokens carry "aud": "account", which tells your API nothing. Add an audience mapper (or a dedicated client scope) so each API receives tokens with its own identifier in aud, and then check it. Our Keycloak token validation for APIs post shows the mapper setup.
  • Rotate keys with overlap. Add a new key provider with a higher priority, let the old key stay available for verification until the tokens it signed have expired, and only then disable it. Verifiers that cache the JWKS by kid will pick up the new key without downtime.
  • Use the typ claim to keep token kinds apart. In the token payload (not the JOSE header), Keycloak puts "typ": "Bearer" in access tokens and "typ": "ID" in ID tokens, and DPoP-bound access tokens carry "typ": "DPoP". Accepting Bearer or DPoP (case-insensitively, since a client setting can lower-case the value) and rejecting ID, Refresh and Logout follows RFC 8725 section 3.12, which asks for mutually exclusive validation rules for different kinds of JWT, and stops an ID token from being replayed as an access token.

In our experience reviewing customer integrations, the most common gap is not the algorithm list but the audience check: plenty of APIs verify the signature and issuer correctly and then accept any valid token from the realm, which means a token issued for one internal tool works against every other API that trusts the same realm. Tightening aud is usually a small change, an audience mapper in Keycloak and one validator in the API, and it is worth doing regardless of CVE-2026-5430.

What should you do if an affected WSO2 deployment was exposed?

If you ran an affected WSO2 version on the internet without the update levels listed above, assume the product’s admin plane could have been reached and work through these steps:

  1. Patch first, using the update level for your product and version, or the community pull requests if you build from source.
  2. Rotate what WSO2 knows. SecurityWeek’s reporting on watchTowr’s testing said a successful bypass exposed API backend endpoints and their credentials. If WSO2 used Keycloak as its key manager, regenerate the secrets of the Keycloak clients whose credentials were stored in WSO2, starting with the client WSO2 uses to call Keycloak’s admin API.
  3. End sessions. In the Keycloak admin console, use the realm’s Sessions page to sign out active sessions for the affected clients or the whole realm, so any tokens obtained with stolen credentials stop being refreshable.
  4. Review logs. Search the WSO2 server logs from 13 September onward for Authentication Failure errors mentioning Public key is not RSA, because in vulnerable builds those lines were written for requests that were then allowed through. Then check Keycloak’s admin events for changes made by the key-manager service account.
  5. Follow CISA’s triage guidance if you are a US federal agency, since the KEV entry requires forensic triage as well as mitigation.

Frequently Asked Questions

What is CVE-2026-5430?

CVE-2026-5430 is a CVSS 10.0 authentication bypass in WSO2 API Manager, API Control Plane, Traffic Manager and Universal Gateway. WSO2’s May 2026 advisory says a JWT signed with an unsupported algorithm could bypass authentication and lead to administrative account takeover. CISA added it to the KEV catalog on 24 September 2026.

Is Keycloak vulnerable to CVE-2026-5430?

No. The flaw is in WSO2’s token verification, not in Keycloak’s token issuance. Keycloak deployments are only exposed indirectly: an attacker who takes over an unpatched WSO2 admin plane can reach the Keycloak client credentials WSO2 stores when Keycloak is its key manager. Patching WSO2 and rotating those credentials closes that gap.

What is a JWT algorithm confusion attack?

It is a class of attacks, described in RFC 8725 section 2.1 (2020), where the verifier lets the token’s alg header decide how to check the signature. The classic forms are alg: none, which skips verification, and switching RS256 to HS256 so the public key is used as an HMAC secret. Allow-listing algorithms on the verifier prevents both.

Which algorithm should I allow for Keycloak access tokens?

Allow exactly the algorithm your realm signs with, which is RS256 by default in Keycloak 26.x. If you have moved the realm to ES256 or another algorithm, allow that one instead. Avoid accepting a list of “everything the library supports”, because RFC 8725 section 3.1 asks for a fixed set chosen by the caller.

Does a short access token lifespan protect against CVE-2026-5430?

Not directly. Keycloak’s five-minute default limits how long a stolen genuine token works, but a forged token accepted by a broken verifier was never issued by Keycloak, so its lifespan is whatever the attacker writes. Short lifespans still help with the secondary risk of leaked credentials after a WSO2 compromise.

What to do next

If you run WSO2 API Manager or any of the three related products, confirm you are on the fixed update level for your version today, because the CVE is on the KEV list and being exploited. Then look at your own resource servers: make sure each one pins RS256 (or your realm’s algorithm), checks iss and aud, and turns every verification error into a 401. Our JWT best practices for developers guide is a good companion checklist for that review.

Sources

  • WSO2, “Security Advisory WSO2-2026-5328/CVE-2026-5430”, published 2026-05-03, retrieved 2026-09-30, https://security.docs.wso2.com/en/latest/security-announcements/security-advisories/2026/WSO2-2026-5328/
  • WSO2, carbon-apimgt pull request #13752, “Improve exception handling”, merged 2026-04-12, retrieved 2026-09-30, https://github.com/wso2/carbon-apimgt/pull/13752
  • WSO2, product-apim pull request #14167, “Improve advanced configuration tests”, merged 2026-04-22, retrieved 2026-09-30, https://github.com/wso2/product-apim/pull/14167
  • CISA, “CISA Adds Two Known Exploited Vulnerabilities to Catalog”, 2026-09-24, retrieved 2026-09-30, https://www.cisa.gov/news-events/alerts/2026/09/24/cisa-adds-two-known-exploited-vulnerabilities-catalog
  • CISA, Known Exploited Vulnerabilities catalog data (version 2026.09.29), retrieved 2026-09-30, https://github.com/cisagov/kev-data
  • SecurityWeek, “Enterprises Warned of Attacks Exploiting WSO2 Vulnerability”, 2026-09-16, retrieved 2026-09-30, https://www.securityweek.com/enterprises-warned-of-attacks-exploiting-wso2-vulnerability/
  • IETF, RFC 8725, “JSON Web Token Best Current Practices”, February 2020, retrieved 2026-09-30, https://www.rfc-editor.org/rfc/rfc8725.html
  • Tim McLean, Auth0 blog, “Critical vulnerabilities in JSON Web Token libraries”, 2015, retrieved 2026-09-30, https://auth0.com/blog/critical-vulnerabilities-in-json-web-token-libraries/
  • WSO2, “Configure Keycloak as a Key Manager”, WSO2 API Manager documentation, retrieved 2026-09-30, https://apim.docs.wso2.com/en/latest/api-security/key-management/third-party-key-managers/configure-keycloak-connector/

Patched on the day, not on your next maintenance window

Keycloak 26.7.2 fixed CVE-2026-18963, an account takeover through password reset. Skycloak had it available for auto-upgrade and told customers the same day upstream shipped it. Self-hosted teams schedule that work themselves.

Guilliano Molaire
Written by
Founder

Guilliano is the founder of Skycloak and a cloud infrastructure specialist with deep expertise in product development and scaling SaaS products. He discovered Keycloak while consulting on enterprise IAM and built Skycloak to make managed Keycloak accessible to teams of every size.

Start Free Trial Talk to Sales
© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman