
Spring Cloud Azure B2C Resource Server Cross-Issuer Authentication Bypass
AadB2cResourceServerAutoConfiguration in spring-cloud-azure-autoconfigure
builds a JwtDecoder that trusts six AAD-line issuers
(login.microsoftonline.com, sts.windows.net, sts.chinacloudapi.cn, v1 and
v2 each) inherited from AadTrustedIssuerRepository via
AadB2cTrustedIssuerRepository.java:30. It installs no tid claim validator,
and the aud predicate uses containsAll (vacuously true on empty audiences).
An attacker with an AAD app registration in the same tenant mints a
client_credentials token whose iss is https://sts.windows.net/<tenant>/
and whose aud matches the B2C app's client-id. The B2C resource server
accepts it because the AAD issuer is in its trusted set and no further claim
validation rejects the cross-identity-system token.
This is the B2C twin of CVE-2026-33117 (AAD resource server). PR #49033 fixed the AAD path; the B2C path was not touched until PR #49252 (merged 2026-06-02, released in the July 2026 Security Update).
With tenant-id=common, any Entra tenant's token is accepted.
Affected: spring-cloud-azure-starter-active-directory-b2c <= 5.19.0.
Fixed in the July 2026 Security Update
(PR #49252).
pip install msal requests
# Against a vulnerable Spring Boot B2C resource server:
python3 poc.py \
--target http://localhost:8080/profile \
--tenant-id <TENANT_ID> \
--client-id <ATTACKER_APP_CLIENT_ID> \
--client-secret <ATTACKER_APP_SECRET> \
--victim-api <B2C_APP_CLIENT_ID>
# Without MSAL (raw HTTP token request):
python3 poc.py \
--target http://localhost:8080/profile \
--tenant-id <TENANT_ID> \
--client-id <ATTACKER_APP_CLIENT_ID> \
--client-secret <ATTACKER_APP_SECRET> \
--victim-api <B2C_APP_CLIENT_ID> \
--no-msal
# Verbose output (full token claims and response):
python3 poc.py ... -v
The attacker app registration needs:
msal, requestsspring-cloud-azure-starter-active-directory-b2c
<= 5.19.0 as the target| File | Description |
|---|---|
poc.py | Python PoC: mints AAD token, sends to B2C endpoint, reports bypass |
README.md | Vulnerability details and usage |
LICENSE | GPLv3 license |
This project is released under the GNU GPLv3.
It is provided for defensive security research, education, and authorized testing. Do not use this code against systems or services without explicit permission from the owner.
Unauthorized use may violate applicable law. The authors do not grant permission to test third-party systems and are not responsible for misuse.
See the LICENSE file for warranty and liability terms.