
CVE-2026-23552 - Cross-Realm Token Acceptance in camel-keycloak
Apache Camel का KeycloakSecurityPolicy JWT टोकन के iss (जारीकर्ता) दावे को कॉन्फ़िगर किए गए realm के विरुद्ध मान्य नहीं करता है। इसका मतलब है कि एक Keycloak realm द्वारा जारी किया गया टोकन पूरी तरह से अलग realm के लिए कॉन्फ़िगर की गई नीति द्वारा चुपचाप स्वीकार कर लिया जाता है, जिससे टेनेंट अलगाव टूट जाता है।
प्रभावित संस्करण: 4.15.0, 4.16.0, 4.17.0
इस पर नज़र रखी गई: https://issues.apache.org/jira/browse/CAMEL-22854
KeycloakSecurityHelper.parseAccessToken() में, जब स्पष्ट रूप से कोई सार्वजनिक कुंजी प्रदान नहीं की जाती है (जो डिफ़ॉल्ट कॉन्फ़िगरेशन है), तो टोकन केवल Base64 से डीकोड किया जाता है -- इसे कभी सत्यापित नहीं किया जाता है:
public static AccessToken parseAccessToken(String tokenString, PublicKey publicKey)
throws VerificationException {
if (publicKey != null) {
return TokenVerifier.create(tokenString, AccessToken.class)
.publicKey(publicKey)
.verify()
.getToken();
} else {
// no signature verification, no issuer check
return TokenVerifier.create(tokenString, AccessToken.class).getToken();
}
}
चूँकि डिफ़ॉल्ट कोड पथ else शाखा पर पहुँचता है, तीन चीज़ें अनियंत्रित रह जाती हैं:
iss दावे की तुलना अपेक्षित {serverUrl}/realms/{realm} से कभी नहीं की जातीभूमिका जाँच अभी भी पास हो जाती है क्योंकि यह केवल टोकन पेलोड के अंदर भूमिका नामों को देखती है। यदि भूमिका का नाम (tenant-user) विभिन्न realms में मेल खाता है -- जो मल्टी-टेनेंट सेटअप में आम है -- तो अनुरोध पास हो जाता है।
ऐसे मल्टी-टेनेंट एप्लिकेशन में जहां प्रत्येक टेनेंट एक अलग Keycloak realm से मैप होता है, टेनेंट A का उपयोगकर्ता टेनेंट B के लिए सुरक्षित रूट्स तक पहुँच सकता है। स्पष्ट रूप से:
यह प्रोजेक्ट Apache Camel 4.17.0 और एक स्थानीय Keycloak इंस्टेंस का उपयोग करके इस भेद्यता को प्रदर्शित करता है।
jbang app install camel@apache/camel)camel infra द्वारा उपयोग किया जाता है)एक स्थानीय Keycloak प्रारंभ करें:
camel infra run keycloak
यह Keycloak को localhost:8080 पर एडमिन क्रेडेंशियल admin/admin के साथ प्रारंभ करता है।
mvn verify
इंटीग्रेशन टेस्ट (CrossRealmTokenBypassIT) निम्नलिखित कार्य करता है:
acme और globextenant-user realm भूमिका बनाता हैacme realm में उपयोगकर्ता alice (पासवर्ड alice123) बनाता है और उसे tenant-user भूमिका प्रदान करता हैglobex realm से बंधी KeycloakSecurityPolicy द्वारा सुरक्षित एक Camel रूट (direct:globex-protected) सेट करता हैacme realm से alice के लिए एक JWT टोकन प्राप्त करता है (जारीकर्ता: http://localhost:8080/realms/acme)अनुरोध सफल होता है। acme टोकन बिना किसी त्रुटि के globex नीति को पास कर जाता है।
| टेस्ट | परिणाम | अर्थ |
|---|---|---|
पैच किए गए संस्करण (4.18.0+) पर, दूसरा परीक्षण विफल हो जाएगा और तीसरा पास हो जाएगा।
camel infra stop keycloak
परीक्षण @AfterAll में acme और globex realms को भी हटा देता है।
KeycloakSecurityPolicy को उन टोकनों को अस्वीकार कर देना चाहिए जहां iss दावा {serverUrl}/realms/{realm} से मेल नहीं खाता। यह समाधान CAMEL-22854 में ट्रैक किया गया है और Camel 4.18.0 (अगले LTS रिलीज़) के साथ जारी किया जाएगा।
testAcmeTokenIsObtainable| PASS |
| सैनिटी जाँच -- टोकन अधिग्रहण कार्य करता है |
testCrossRealmTokenAccepted | PASS | पुष्टि करता है कि भेद्यता मौजूद है |
testCrossRealmTokenShouldBeRejected | FAIL | सही व्यवहार का दस्तावेज़ीकरण करता है -- 4.17.0 पर कोई अपवाद नहीं फेंका जाता |