Back to Blog
high SEVERITY4 min read

ip-address 10.2.0 SSRF: Inconsistent Parsing Bypasses IP Checks

The `ip-address` npm package version 10.2.0 contains an inconsistent parsing vulnerability that allows attackers to bypass IP-based access controls. By representing IPv4 addresses in IPv4-mapped IPv6 notation, attackers can trick applications into allowing requests to blocked internal addresses. Upgrading to 10.3.1 resolves this through stricter address normalization.

O
By Orbis AppSec
Published September 14, 2026Reviewed September 14, 2026

Answer Summary

The `ip-address` npm package versions 10.2.0 and earlier are affected. An attacker can bypass SSRF protections and access internal services by representing blocked IPv4 addresses as IPv4-mapped IPv6 addresses (e.g., `::ffff:127.0.0.1`), which the vulnerable parser treats as distinct from their IPv4 equivalents. The fix in version 10.3.1 ensures consistent canonicalization of these address forms. CWE is unknown.

Vulnerability at a Glance

cweN/A
fixUpgrade to ip-address 10.3.1 with stricter address normalization
riskBypass of IP-based access controls to reach internal services
languageJavaScript/TypeScript
root causeInconsistent parsing of IPv4-mapped IPv6 addresses versus their IPv4 equivalents
vulnerabilityServer-Side Request Forgery (SSRF)

When your application checks whether an IP address is "internal" or "external," it relies on the parser to speak the same language as the network stack. In ip-address 10.2.0, that assumption broke down: the same logical address could wear two different masks—one IPv4, one IPv6—and slip past defenses designed to stop it.

Affected Versions

Affected >= 8.0.0, <= 10.2.0
Fixed in 10.3.1
Ecosystem npm
CVE / GHSA CVE-2026-69192 / not assigned
CWE unknown

The Vulnerability Explained

The ip-address package provides JavaScript implementations of IPv4 and IPv6 address parsing, manipulation, and comparison. Version 10.2.0 introduced—or failed to resolve—a subtle inconsistency in how IPv4-mapped IPv6 addresses are handled.

An IPv4-mapped IPv6 address represents an IPv4 address within the IPv6 address space using the prefix ::ffff:. For example, 127.0.0.1 becomes ::ffff:127.0.0.1 or its full IPv6 form ::ffff:7f00:0001. These are semantically equivalent: they refer to the exact same network endpoint.

The vulnerability arises when applications use ip-address to validate whether a target address is "safe" to connect to. Consider this common SSRF protection pattern:

const { Address4, Address6 } = require('ip-address');

function isInternalIP(ipString) {
  let addr;
  try {
    addr = new Address4(ipString);
  } catch {
    try {
      addr = new Address6(ipString);
    } catch {
      return false; // Not a valid IP
    }
  }

  // Block loopback, private ranges, etc.
  return addr.isLoopback() || addr.isPrivate();
}

// Blocklist check
if (!isInternalIP(userProvidedIP)) {
  fetch(`http://${userProvidedIP}/admin`); // "Safe" to request
}

An attacker providing 127.0.0.1 is blocked. But providing ::ffff:127.0.0.1? In 10.2.0, the Address6 parser creates a distinct object whose isLoopback() method may return false or whose comparison against IPv4 loopback ranges fails to match—despite targeting identical infrastructure.

This trust-boundary bypass lets attackers reach:
- Internal admin panels (::ffff:10.0.0.1)
- Metadata services (::ffff:169.254.169.254)
- Database instances (::ffff:192.168.1.100)

The root cause: ip-address 10.2.0 failed to canonicalize IPv4-mapped IPv6 addresses to their IPv4 form before performing semantic comparisons. Two addresses that are network-equivalent were treated as distinct objects.

The Fix

Version 10.3.1 resolves this through stricter normalization. When parsing an IPv4-mapped IPv6 address, the library now converts it to its canonical IPv4 representation before any classification or comparison operations.

The dependency upgrade is enforced across the entire tree using npm's overrides mechanism:

{
  "overrides": {
    "imapflow": {
      "ip-address": "10.3.1"
    },
    "ip-address": {
      "ip-address": "10.3.1"
    },
    "socks": {
      "ip-address": "10.3.1"
    }
  }
}

This ensures that even transitive dependencies—imapflow for IMAP connections, socks for proxy handling—use the patched version, eliminating the parsing inconsistency wherever IP validation occurs.

The version bump in package-lock.json reflects this coordinated upgrade:

-      "version": "10.2.0",
-      "resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-10.2.0.tgz",
+      "version": "10.3.1",
+      "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.3.1.tgz",

Key Takeaways

  • IPv4-mapped IPv6 addresses are not "different" addresses—they're the same endpoint in different clothing. Any IP validation that doesn't canonicalize these forms creates a bypass opportunity.

  • Network-layer equivalence ≠ object equality in your parser. The ip-address package's Address4 and Address6 classes being separate types created a semantic gap that attackers could exploit.

  • Transitive dependencies need coercion. The overrides field in package.json is essential for forcing security fixes through deeply nested dependency trees where direct control is limited.

  • SSRF defenses must normalize before validating. Checking isLoopback() or isPrivate() on non-canonicalized addresses is insufficient; the normalization step must happen first.

  • Dual-stack environments amplify this risk. Applications running on Node.js with IPv6 enabled (the default since Node 17) are more exposed, as the network stack itself will accept and route these mapped addresses.

How Orbis AppSec Detected This

Source: User-influenced input reaching the ip-address parser through HTTP request parameters or configuration values.

Sink: The Address4 and Address6 constructors and their classification methods (isLoopback(), isPrivate(), isInSubnet()) used for SSRF access control decisions.

Missing control: Canonicalization of IPv4-mapped IPv6 addresses to a single comparable form before trust-boundary checks.

CWE: unknown

Fix: Force-upgrade to ip-address 10.3.1 using npm overrides to ensure consistent address normalization across all dependencies.

Orbis AppSec automatically detected this vulnerability and opened a pull request with the fix. Try Orbis AppSec on your repositories to find and fix issues like this automatically.

Conclusion

CVE-2026-69192 is a reminder that security boundaries live in the gaps between representations. The ip-address 10.2.0 parser saw 127.0.0.1 and ::ffff:127.0.0.1 as different enough to defeat access controls, while the network stack saw them as identical. The 10.3.1 fix closes this gap by ensuring the parser's worldview matches reality—one canonical form, one truth, no bypass.

Prevention and further reading

Frequently Asked Questions

Does ip-address 10.3.1 treat `::ffff:127.0.0.1` and `127.0.0.1` as the same address?

Yes. The fix ensures IPv4-mapped IPv6 addresses are canonicalized to their IPv4 form before comparison, eliminating the parsing inconsistency that allowed SSRF bypasses.

Which transitive dependencies of ip-address are force-updated by the npm overrides in the fix?

The fix applies forced upgrades to `imapflow`, `ip-address` itself, and `socks` to ensure the entire dependency tree uses the patched version 10.3.1.

Is the CVE-2026-69192 vulnerability exploitable if my application only validates IPv4 addresses with a regex?

No—the vulnerability specifically affects applications using the `ip-address` package's parsing API. Pure regex validation would reject `::ffff:` prefixed addresses entirely, though this is not a recommended security pattern.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #23

Related Articles

medium

How gitlab.bandit.B501 happens in Python and how to fix it

The `proverbia-scraper.py` script disabled TLS certificate verification on its `requests.get()` call and silenced the resulting security warnings, exposing the scraper to man-in-the-middle attacks. The fix removes the `verify=False` flag and the warning suppression, restoring proper certificate validation while keeping the existing 30-second timeout intact.

high

How Server-Side Request Forgery (SSRF) happens in Go HTTP handlers and how to fix it

A Server-Side Request Forgery (SSRF) vulnerability was discovered in `internal/web/controller/server.go` where the `applySubTemplate` endpoint accepted arbitrary URLs from user input and passed them directly to `serverService.ApplySubTemplateFromGithub()` without any host validation. An attacker could exploit this to make the server issue HTTP requests to internal network resources, cloud metadata endpoints, or redirect-controlled destinations. The fix introduces a strict allowlist that restrict

critical

How SSRF via Vulnerable Dependency Versions Happens in Node.js and How to Fix It

A permissive semver range in `package.json` allowed npm to install axios versions vulnerable to SSRF (CVE-2024-39338). By bumping the minimum version from `^1.6.0` to `^1.7.4`, all downstream consumers of this SDK are now protected from server-side request forgery attacks. This critical fix required changing just one line in the dependency manifest.

critical

How Server-Side Request Forgery happens in Python FastAPI and how to fix it

A critical Server-Side Request Forgery (SSRF) vulnerability was discovered in app.py where the `/parse` and `/parse-video` endpoints accepted user-supplied URLs with only substring validation. The application checked if 'doubao.com' appeared anywhere in the URL string, allowing attackers to bypass this check and access internal services, cloud metadata endpoints, or scan the internal network. The fix implemented proper hostname parsing with an allowlist of legitimate domains.

critical

How Server-Side Request Forgery happens in Node.js maintenance scripts and how to fix it

A critical Server-Side Request Forgery (SSRF) vulnerability was discovered in `maintenance/getImages.js`, where the `getImage()` function passed database-sourced URLs directly to `axios.get()` without any validation. An attacker who could modify the elements database could redirect these requests to internal network resources — including AWS cloud metadata endpoints — potentially exposing IAM credentials and other sensitive infrastructure data. The fix introduces a strict URL allowlist that limi

high

modelExporter.js Path Traversal via Unsanitized Directory Concatenation

A path traversal vulnerability in `modelExporter.js` allowed attackers to read arbitrary files by injecting traversal sequences into directory and relative path parameters. The `readSourceFile` function concatenated these unsanitized inputs directly into file URLs passed to `fetch()`. The fix introduces strict path normalization that rejects attempts to escape the intended directory.