Mar 19, 2026·6 min read·23 visits
A high-severity parsing flaw in segmentio/encoding enables JSON key collusion via null byte injection. Attackers can bypass WAFs and overwrite critical struct fields in the MCP Go SDK by appending \u0000 to JSON keys.
The Model Context Protocol (MCP) Go SDK, via its dependency on segmentio/encoding, is vulnerable to JSON Key Collusion. The JSON parser improperly handles null Unicode characters during struct field mapping, allowing attackers to smuggle overriding keys past security filters and manipulate backend application logic.
The vulnerability resides in the Model Context Protocol (MCP) Go SDK, specifically within its underlying JSON parsing dependency, segmentio/encoding. The parser fails to properly validate the length of incoming JSON keys against the length of the matched target struct field names. This lack of validation allows attackers to inject null Unicode characters (\u0000) into JSON keys without disrupting the internal field mapping process.
Because the high-performance parser ignores the trailing null byte, it maps the malicious key to the exact same struct field as the legitimate key. This behavior creates a JSON Key Collusion vulnerability, where two apparently distinct keys resolve to a single destination. The flaw is formally classified under CWE-20 (Improper Input Validation) and carries a high severity score of 8.2.
This vulnerability exposes applications to semantic smuggling attacks when deployed behind intermediate security proxies. Standard JSON parsers used by Web Application Firewalls (WAFs) and API gateways interpret the keys as entirely distinct entities. The vulnerable backend merges them, enabling attackers to bypass front-end security validation and inject unauthorized variables into the application state.
The root cause exists within the keyset.Lookup function of the segmentio/encoding library. This function employs SIMD-optimized routines and fallback hashing to rapidly map incoming JSON keys to the fields of a compiled Go struct. The implementation prioritizes speed and executes a lookup algorithm that identifies matching field names without strictly verifying the total byte length of the input key.
Prior to version 0.5.4, the algorithm treated the null character (\u0000 or \x00) as an acceptable string terminator or ignorable padding. When the parser encountered a key containing a null byte appended to a valid field name, the lookup logic successfully matched the prefix and halted evaluation. It subsequently returned the internal index of the matched struct field, completely disregarding the injected null bytes.
This behavior directly contradicts the JSON specification and standard Go encoding/json behavior, which require exact string matches for automatic struct unmarshaling. The divergence in parsing logic creates a reliable semantic differential. The parser processes the maliciously crafted key as identical to the standard key, subsequently applying the "last-key-wins" rule standard to JSON deserialization.
The vulnerable code pattern relies on a fast-path lookup that establishes a match based on partial string identity. The keyset.Lookup function locates the corresponding field index but omits the crucial validation step ensuring the input key length matches the target field length.
// Vulnerable Implementation (Conceptual)
if n := keyset.Lookup(st.keyset, k); n < len(st.fields) {
// Match made without strict length check
// "admin\u0000" resolves to the "admin" field index
f = &st.fields[n]
}The fix introduced in segmentio/encoding commit 7d5a25dbc5da13aed3cb047a127e4d0e96f536fb remediates this by enforcing an explicit length boundary. The patch modifies the decodeStruct function to verify that the length of the parsed JSON key exactly matches the length of the identified struct field name before allowing the assignment.
// Patched Implementation (segmentio/encoding v0.5.4)
if n := keyset.Lookup(st.keyset, k); n < len(st.fields) {
// Explicit length verification added
if len(st.fields[n].name) == len(k) {
f = &st.fields[n]
}
}This patch robustly eliminates the null-byte injection vector. The maintainers also introduced specific fuzzing targets (FuzzUnmarshalKeyComparison and FuzzUnmarshalFieldIsolation) to verify the fix. These fuzzing tests confirm that the strict length check successfully isolates struct fields from any further key collusion techniques.
Attackers exploit this vulnerability by crafting JSON payloads containing duplicate keys targeting the same configuration field. The first key contains the legitimate field name and a safe value designed to pass initial WAF inspection. The second key appends a null byte to the field name and supplies the malicious payload.
{
"admin": false,
"admin\u0000": true
}When this payload traverses a security boundary, a standard JSON parser evaluates the data. The WAF observes two distinct keys: "admin" and "admin\u0000". The WAF typically validates the first key, confirms the value is false, and permits the request. Some WAFs may implicitly drop the malformed second key, but many forward the raw payload intact to the backend application.
The vulnerable backend application utilizing modelcontextprotocol/go-sdk deserializes the forwarded payload. The segmentio/encoding library maps both "admin" and "admin\u0000" to the internal Admin struct field. Processing the keys sequentially, the parser writes false to the struct, and then immediately overwrites it with true upon processing the colluding key.
The security impact of this vulnerability is significant due to its ability to bypass front-end access controls. An attacker successfully exploiting this flaw gains the ability to manipulate arbitrary struct fields exposed via the JSON decoding boundary. This directly enables privilege escalation, configuration tampering, and logic bypasses depending on the application's specific architecture.
The severity score of 8.2 reflects the high integrity impact and the low complexity of the network-based attack vector. The vulnerability requires no authentication to trigger at the parser level, though the ultimate impact depends entirely on the privileges associated with the targeted endpoint. The exploitation process requires no specialized tools beyond standard HTTP clients.
This vulnerability highlights the inherent risks of parser differentials in distributed architectures. Relying on differing JSON parsing implementations between security edge devices and core backend services consistently produces blind spots. Applications utilizing custom or high-performance serialization libraries face elevated risks of semantic smuggling when interacting with strictly compliant middleware.
The primary remediation strategy requires updating the vulnerable packages to their patched versions. Applications utilizing the Model Context Protocol Go SDK must upgrade github.com/modelcontextprotocol/go-sdk to version v0.5.4. This release updates the module dependencies to enforce the secure version of the underlying encoding library.
Developers using the github.com/segmentio/encoding library directly must upgrade their dependencies to v0.5.4 or later. Go applications should utilize go get github.com/segmentio/encoding@v0.5.4 followed by go mod tidy to ensure the correct version is locked in the dependency tree. Recompilation and redeployment of the application are strictly required to apply the fix.
Organizations unable to deploy immediate patches can implement mitigation strategies at the ingress proxy level. Web Application Firewalls (WAFs) and API gateways must be configured to categorically reject HTTP requests containing JSON bodies with duplicate keys or encoded null characters (\u0000 or \x00). Implementing strict schema validation at the edge significantly reduces the exploitability of parser differential vulnerabilities.
| Product | Affected Versions | Fixed Version |
|---|---|---|
github.com/modelcontextprotocol/go-sdk Model Context Protocol | < v0.5.4 | v0.5.4 |
github.com/segmentio/encoding Segmentio | < v0.5.4 | v0.5.4 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-20 |
| Attack Vector | Network |
| CVSS Score | 8.2 |
| Impact | Integrity Violation / Privilege Escalation |
| Exploit Status | Proof of Concept Available |
| CISA KEV | Not Listed |
Improper Input Validation allowing for JSON Key Collusion via null byte injection.
The @jhb.software/payload-cloudinary-plugin exposes an endpoint that performs unvalidated cryptographic signing of Cloudinary API parameters, allowing authenticated users with minimal privileges to forge valid signatures for arbitrary actions. This flaw allows attackers to overwrite remote storage assets, execute unauthorized file uploads, alter asset visibility parameters, trigger SSRF webhooks, and perform directory traversal within Cloudinary repositories.
A Server-Side Request Forgery (SSRF) and Bearer Token Exfiltration vulnerability exists in the @merill/lokka (Lokka) Model Context Protocol (MCP) server prior to version 2.1.2. The server constructed Azure Resource Manager request URLs by concatenating user-controlled path parameters directly into destination request strings. By injecting authority-redefinition characters, an attacker can manipulate URL parsing to execute a host-escape attack, forcing the server to send high-privilege Azure Resource Manager (ARM) Bearer tokens to an external attacker-controlled host. This allows complete administrative access to the associated Azure subscriptions.
A directory traversal and symlink following vulnerability exists in Pydantic Settings when using the NestedSecretsSettingsSource with nested subdirectory lookups enabled. An attacker capable of writing to the secrets directory can bypass size limitations, read arbitrary host files, or cause a denial-of-service condition via cyclic symlinks.
A Server-Side Request Forgery (SSRF) vulnerability exists in SurrealDB's Identity & Access Management (IAM) module prior to version 3.1.5. When configuring JSON Web Key Set (JWKS) URLs for token verification, the remote fetcher follows HTTP redirects by default without validating redirect targets against configured network capabilities. This allows high-privileged users to bypass network access limits and perform blind port scanning of internal network resources.
A local file disclosure vulnerability exists in SurrealDB's full-text search capabilities, allowing authenticated users with database EDITOR or OWNER roles to read arbitrary files from the host system filesystem. This occurs by abusing the mapper() filter inside a DEFINE ANALYZER statement to point to system files.
SurrealDB versions 3.0.0 through 3.1.4 contain an information exposure vulnerability (CWE-203) where the query planner optimizes sorted queries using indexes on fields with field-level SELECT restrictions. Because the query planner performs index-based sorting before enforcing permission-based redaction, unauthorized users can observe the physical order of returned rows to deduce the relative values of protected fields.