Back to Blog
high SEVERITY7 min read

How SSRF via IP Address Parsing Inconsistency happens in Node.js and how to fix it

A critical parsing inconsistency in the ip-address npm package (versions before 10.3.1) allowed Server-Side Request Forgery (SSRF) and trust-boundary bypass. The library decoded IP addresses with leading-zero octets as decimal (e.g., 0127.0.0.1 as 127.0.0.1), while DNS resolvers and system libraries interpreted them as octal (e.g., 0127 as 87 decimal), enabling attackers to bypass IP allowlists and access internal resources.

O
By Orbis AppSec
Published August 15, 2026Reviewed August 15, 2026

Answer Summary

CVE-2026-69192 is an SSRF vulnerability in the ip-address npm package (CWE-918) caused by inconsistent parsing of IP addresses with leading-zero octets. The Address4 class decoded "0127.0.0.1" as decimal 127.0.0.1, while DNS resolvers interpreted it as octal (87.0.0.1), allowing attackers to bypass IP allowlists and access internal services. The fix upgrades ip-address from 10.2.0 to 10.3.1, which normalizes leading-zero handling to match resolver behavior and prevent trust-boundary bypass.

Vulnerability at a Glance

cweCWE-918 (Server-Side Request Forgery)
fixUpgrade ip-address from 10.2.0 to 10.3.1 to align parsing with resolver behavior
riskAttackers can bypass IP allowlists to access internal services
languageJavaScript/Node.js
root causeip-address library decoded leading-zero octets as decimal while resolvers used octal
vulnerabilitySSRF via IP Address Parsing Inconsistency

The Hidden Danger in IP Address Parsing

In the devboard server component, we discovered a high-severity SSRF vulnerability in devboard/server/package-lock.json affecting the ip-address npm package. This wasn't a typical SSRF where validation was missing—it was far more subtle. The application was validating IP addresses, but the validation library and the DNS resolver were speaking different languages when it came to leading-zero octets.

The ip-address package version 10.2.0 decoded an address like 0127.0.0.1 as decimal, treating the leading zero as insignificant. It would parse this as 127.0.0.1 (localhost). However, when the actual HTTP request was made, the system's DNS resolver or network stack interpreted 0127 as octal (base-8), converting it to decimal 87. The result? The application thought it was blocking requests to localhost, but attackers could bypass the check and reach 87.0.0.1 instead—potentially an internal service on the network.

This parsing inconsistency created a trust-boundary bypass that could allow attackers to probe internal networks, access cloud metadata services, or interact with services that should be unreachable from external input.

The Vulnerability Explained

The vulnerability exists in how the Address4 class of the ip-address library (version 10.2.0 and earlier) handles IP address strings with leading zeros in octets. Let's examine the specific problem:

// Vulnerable code behavior in ip-address 10.2.0
const Address4 = require('ip-address').Address4;

// Application validates user input
const userInput = '0127.0.0.1';
const addr = new Address4(userInput);

// ip-address 10.2.0 interprets this as decimal
console.log(addr.address); // "127.0.0.1" - decimal interpretation

// But when this address is used in an HTTP request...
fetch(`http://${userInput}/api/data`)
// The system resolver interprets 0127 as OCTAL
// 0127 (octal) = 87 (decimal)
// Actual request goes to 87.0.0.1, not 127.0.0.1!

The attack scenario is straightforward but devastating:

  1. Setup: The devboard server has an allowlist blocking requests to internal IP ranges, including 127.0.0.0/8 (localhost)
  2. Validation: Application uses ip-address 10.2.0 to parse user-supplied target URLs
  3. Bypass: Attacker provides http://0177.0.0.1/admin as a webhook URL
  4. Validation passes: ip-address interprets this as 127.0.0.1 (decimal), which is correctly blocked
  5. Execution differs: The actual HTTP client's resolver interprets 0177 as octal = 127 decimal, accessing localhost
  6. Result: Attacker accesses internal admin panel that should be unreachable

An even more dangerous variant:

// Attacker targets AWS metadata service (169.254.169.254)
const malicious = '0251.0254.0251.0254';

// ip-address 10.2.0 sees: 251.254.251.254 (decimal) - NOT in AWS range
// Validation: PASS ✓

// System resolver sees: 169.254.169.254 (octal conversion) - AWS metadata!
// Actual request: SSRF to cloud credentials ✗

This specific vulnerability in the devboard server's dependency tree meant that any component using ip-address for validation before making HTTP requests was vulnerable to this bypass technique.

The Fix

The fix was implemented by upgrading the ip-address package from version 10.2.0 to 10.3.1 in the devboard server dependencies. Here's what changed:

Before (vulnerable - ip-address 10.2.0):

"node_modules/ip-address": {
  "version": "10.2.0",
  "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz",
  "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA=="
}

After (fixed - ip-address 10.3.1):

"node_modules/ip-address": {
  "version": "10.3.1",
  "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.3.1.tgz",
  "integrity": "sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g=="
}

The fix also added a package override in devboard/server/package.json to ensure the correct version is enforced across the entire dependency tree:

"overrides": {
  "ip-address": "10.3.1"
}

This override is crucial because ip-address might be a transitive dependency (pulled in by other packages), and the override ensures that even indirect dependencies use the patched version.

How the fix works:

Version 10.3.1 of ip-address changes the parsing behavior to align with how DNS resolvers and network stacks interpret IP addresses. Specifically:

  1. Consistent octal handling: Leading-zero octets are now treated as octal, matching system resolver behavior
  2. Normalization: IP addresses are canonicalized to their true numeric values before validation
  3. Rejection option: The library can now reject ambiguous formats entirely in strict mode

The security improvement is concrete: after this upgrade, when the application validates 0127.0.0.1, the ip-address library now interprets it the same way the HTTP client will—as octal, converting to 87.0.0.1. If 87.0.0.1 is on the blocklist, the validation correctly rejects it. The trust boundary is restored.

Both files were modified because:
- package.json adds the override to enforce the version policy
- package-lock.json records the exact resolved version and integrity hash for reproducible builds

Prevention & Best Practices

To avoid IP address parsing vulnerabilities in your Node.js applications:

1. Use Canonical Forms for Validation

Always normalize IP addresses to their canonical form before comparing against allowlists or blocklists:

const Address4 = require('ip-address').Address4;

function isAllowed(ipString) {
  try {
    const addr = new Address4(ipString);
    const canonical = addr.canonicalForm(); // e.g., "127.0.0.1"

    // Now validate against canonical form
    return !isPrivateIP(canonical);
  } catch (e) {
    // Invalid IP - reject
    return false;
  }
}

2. Validate After Parsing, Not Before

Don't validate the string representation—validate the parsed numeric value:

// BAD: String comparison
if (ipString.startsWith('127.')) { /* block */ }

// GOOD: Numeric comparison after parsing
const addr = new Address4(ipString);
if (addr.parsedAddress[0] === 127) { /* block */ }

3. Keep IP Parsing Libraries Updated

IP address parsing is deceptively complex. Libraries like ip-address handle edge cases including:
- Leading zeros (octal ambiguity)
- IPv4-mapped IPv6 addresses
- Hexadecimal notation
- Integer notation (e.g., 2130706433 = 127.0.0.1)

Use dependency scanning tools like Trivy, Snyk, or npm audit to catch vulnerable versions.

4. Implement Defense in Depth

Don't rely solely on IP validation:
- Use network segmentation to isolate internal services
- Implement application-level authentication for all services
- Monitor for unusual outbound connection patterns
- Use DNS rebinding protection (check IP at connection time, not just resolution time)

5. Test with Ambiguous Formats

Include test cases with tricky IP formats:

const testCases = [
  '0127.0.0.1',      // Octal
  '0x7f.0.0.1',      // Hexadecimal
  '2130706433',      // Integer notation
  '127.0.0.0x1',     // Mixed formats
  '127.1',           // Abbreviated
];

6. Reference Security Standards

  • CWE-918: Server-Side Request Forgery (SSRF) - understand the attack class
  • CWE-436: Interpretation Conflict - recognize parsing inconsistencies as a root cause
  • OWASP SSRF Prevention Cheat Sheet: comprehensive guidance on preventing SSRF attacks

Key Takeaways

  • The ip-address 10.2.0 library decoded leading-zero octets as decimal while DNS resolvers used octal, creating a parsing gap exploitable for SSRF attacks in the devboard server component
  • String-based IP validation is insufficient—always parse to canonical form before comparing against allowlists to prevent format-based bypasses like 0127.0.0.1
  • Package overrides in package.json are essential when fixing transitive dependencies, ensuring that ip-address 10.3.1 is used even when pulled in indirectly by other packages
  • Ambiguous IP formats (octal, hex, integer notation) are attack vectors—use libraries that normalize these to canonical forms or reject them in strict mode
  • CVE-2026-69192 demonstrates that even well-intentioned validation can fail when the validator and executor interpret data differently, highlighting the importance of semantic consistency across security boundaries

How Orbis AppSec Detected This

  • Source: User-influenced input in webhook URLs, API target addresses, or other fields where the devboard server accepts IP addresses for outbound connections
  • Sink: HTTP request functions (fetch, axios, http.request) that resolve and connect to the user-supplied IP address after validation by ip-address 10.2.0
  • Missing control: Consistent parsing between the validation layer (ip-address library) and the execution layer (system DNS resolver), allowing octal-format addresses to bypass decimal-based allowlist checks
  • CWE: CWE-918 (Server-Side Request Forgery) with contributing CWE-436 (Interpretation Conflict)
  • Fix: Upgraded ip-address from 10.2.0 to 10.3.1, which aligns octal handling with system resolver behavior, and added package override to enforce the version across the dependency tree

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 in the ip-address npm package demonstrates how subtle parsing inconsistencies can create serious security vulnerabilities. The devboard server's upgrade from ip-address 10.2.0 to 10.3.1 closes a trust-boundary bypass that could have allowed attackers to access internal services through SSRF attacks exploiting octal notation.

This vulnerability reinforces a critical principle: security validation must use the same interpretation rules as the enforcement mechanism. When your allowlist validator sees "127.0.0.1" but your HTTP client connects to "87.0.0.1", you don't have security—you have a false sense of security.

By keeping dependencies updated, validating parsed canonical forms rather than string representations, and testing with ambiguous input formats, you can prevent similar vulnerabilities in your own applications. The automated detection and fix by Orbis AppSec shows how modern security tooling can catch these issues before they reach production.

References

Frequently Asked Questions

What is SSRF via IP address parsing inconsistency?

It's a vulnerability where differences in how applications and DNS resolvers parse IP addresses allow attackers to craft addresses that bypass security checks. Specifically, leading-zero octets like "0127" are interpreted as decimal by some libraries but octal (base-8) by DNS resolvers, creating a mismatch exploitable for SSRF.

How do you prevent SSRF via IP parsing inconsistency in Node.js?

Always use up-to-date IP parsing libraries that normalize addresses consistently with system resolvers, validate IP addresses after parsing against allowlists using canonical forms, and never trust user-supplied IP addresses without normalization. The ip-address package version 10.3.1+ fixes this specific inconsistency.

What CWE is SSRF via IP parsing inconsistency?

This vulnerability maps to CWE-918 (Server-Side Request Forgery) as the primary classification, with contributing factors from CWE-436 (Interpretation Conflict) since the attack exploits different interpretations of the same IP address string between the validation layer and the execution layer.

Is IP allowlist validation enough to prevent SSRF?

No, not if the validation uses a different parsing method than the component making the actual request. As CVE-2026-69192 demonstrates, an allowlist checking "127.0.0.1" can be bypassed with "0127.0.0.1" if the validator decodes it as decimal (127.0.0.1, allowed) but the HTTP client's resolver decodes it as octal (87.0.0.1, different address).

Can static analysis detect IP parsing inconsistencies?

Yes, dependency scanners like Trivy can detect known vulnerable versions of IP parsing libraries. However, detecting novel parsing inconsistencies requires semantic analysis that understands both the application's validation logic and the downstream resolver behavior, which is why keeping dependencies updated is critical.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #267

Related Articles

high

How Octal IP Address Parsing Inconsistency Enables SSRF in Node.js and How to Fix It

A critical parsing inconsistency in the `ip-address` npm package (version 10.2.0) allowed attackers to bypass SSRF protections by exploiting how leading-zero octets are interpreted differently—decimal by the library versus octal by system resolvers. This vulnerability (CVE-2026-69192) was fixed by upgrading to version 10.3.1 using an npm override, ensuring consistent IP address validation across the application.

high

How NO_PROXY bypass via crafted URL happens in Node.js axios and how to fix it

A high-severity vulnerability (CVE-2026-42043) in the axios HTTP client library allowed attackers to bypass NO_PROXY environment variable restrictions using specially crafted URLs. This could route sensitive internal traffic through attacker-controlled proxy servers. The fix upgrades axios from 1.13.6 to 1.18.0, which includes a rewritten proxy resolution mechanism using `proxy-from-env` v2.1.0 and the `https-proxy-agent` package.

high

How Server-Side Request Forgery (SSRF) happens in Node.js through inconsistent IP address parsing and how to fix it

A high-severity Server-Side Request Forgery (SSRF) vulnerability (CVE-2026-69192) was discovered in the ip-address package version 10.2.0, where inconsistent IP address parsing allowed attackers to bypass trust boundaries and access internal resources. The fix upgrades ip-address from 10.2.0 to 10.3.1 across the dependency tree, with explicit pinning in package.json and strategic version management in bun.lock to prevent both direct and transitive exploitation paths.

critical

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

A critical Server-Side Request Forgery (SSRF) vulnerability was discovered in `libraries/microworlds/video.js` where the `VideoCanvasWrapper.loadVideo()` function passed user-controlled URLs directly to `fetch()` without any validation. An attacker could exploit this by supplying URLs pointing to internal services, localhost endpoints, or malicious external servers. The fix introduces strict URL parsing and protocol validation before any network request is made.

high

How IP Address Parsing Inconsistency Happens in Node.js and How to Fix It

CVE-2026-69192 revealed a critical inconsistency in the `ip-address` npm package where the `Address4` class decoded leading-zero octets as decimal while standard DNS resolvers interpreted them as octal, creating a trust-boundary bypass and SSRF attack vector. The fix upgrades `ip-address` from version 10.2.0 to 10.3.1 in the CanvaLight plugin, correcting the parsing behavior to match resolver expectations.

high

How Command Injection happens in Node.js child_process calls and how to fix it

A high-severity command injection vulnerability was discovered in `src/collectors/git.ts`, where `execSync` was used to build a shell command by interpolating unsanitized arguments into a template string. By replacing `execSync` with `spawnSync`, the fix eliminates shell interpretation entirely, ensuring that git arguments are passed directly to the process without ever touching a shell. This change is especially important for a Node.js library, where downstream consumers may pass user-controlle