CVE-2026-89315 in KeyPont
Summary
by MITRE • 10/23/2026
`JwtClaims.MarshalJSON` built a Go struct at runtime with `reflect.StructOf`, synthesising a field named `"A" + claimName` for each untyped claim. `reflect.StructOf` **panics** when a field name is not a valid Go identifier, or when it duplicates another field. Both conditions are reachable from ordinary JWT claim names.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 10/23/2026
The vulnerability resides in the JwtClaims.MarshalJSON function within a Go-based JSON Web Token implementation, where dynamic struct generation introduces critical runtime stability risks. The core technical flaw involves the use of reflect.StructOf to construct a new struct type at execution time for each invocation that requires marshaling JWT claims into JSON format. This process iterates over untyped claim data and attempts to create corresponding fields in the synthesized struct by concatenating the prefix "A" with the original claim name, resulting in field identifiers such as Aiss or Aexp. While this approach allows for flexible handling of arbitrary claim names without predefined schema constraints, it fails to validate whether these dynamically generated identifiers comply with Go language specifications regarding valid identifier syntax.
In the Go programming language, a valid identifier must begin with a letter or underscore and consist only of letters, digits, and underscores. It cannot contain special characters such as hyphens, spaces, dots, or symbols like @ or #. When an attacker supplies a JWT containing claims with names that include invalid characters—for instance A-user-id or A.email—the reflect.StructOf function encounters these malformed identifiers during struct construction. Instead of gracefully handling the error or rejecting the input, the reflection package triggers a panic due to the violation of identifier naming rules. This results in immediate termination of the goroutine executing the marshaling operation, which can lead to service unavailability if not properly recovered from at higher levels of the application stack.
Furthermore, the vulnerability extends beyond simple syntax violations through duplicate field name collisions. The reflect.StructOf function also panics when two or more fields within the same struct share identical names. Since JWT claims are often user-controlled and may contain repeated keys in malformed tokens, an attacker can craft a token with multiple claim entries that resolve to the same synthesized identifier after prefixing. For example if two different raw claims both map to Asub due to normalization issues or intentional duplication attempts, the reflection mechanism will detect conflicting field definitions and panic. This creates a reliable denial-of-service vector against any service relying on this library for JWT parsing and serialization operations.
The operational impact of these panics is significant in production environments where availability is paramount. Because Go does not automatically recover from all types of reflection-induced panics unless explicitly handled via defer-recover blocks, unhandled occurrences will crash the associated goroutine. In web servers or microservices processing high volumes of JWTs, such crashes can cause thread pool exhaustion, request timeouts, and cascading failures across dependent services. Attackers do not need to execute arbitrary code; they merely need to submit specially crafted tokens with invalid claim names or duplicate keys to disrupt service continuity. This aligns closely with CWE-617 which describes improper handling of runtime errors leading to denial-of-service conditions through unhandled exceptions or panics in compiled languages like Go.
From a threat modeling perspective, this vulnerability maps directly to ATT&CK technique T1499 Endpoint Denial of Service where adversaries leverage software flaws to degrade system performance or availability. The attack vector is remote and requires no authentication if the JWT validation logic processes incoming tokens before strict schema enforcement occurs. This makes it particularly dangerous in public-facing APIs that accept user-supplied JWTs for session management, authorization checks, or data exchange protocols.
Mitigation strategies should focus on implementing robust input validation prior to reflection-based struct generation. Developers must sanitize claim names by replacing invalid characters with underscores or removing them entirely before constructing field identifiers. Additionally enforcing uniqueness among synthesized field names through deduplication logic prevents collision-induced panics. Alternatively shifting away from dynamic struct creation toward static mapping structures or map[string]interface serialization bypasses the reflect package altogether eliminating this class of vulnerabilities. Adopting stricter JWT parsing libraries that validate claim formats against RFC 7519 standards during initial token ingestion rather than at marshaling time provides defense in depth and reduces exposure surface area for reflection-based attacks.