Back to Blog
high SEVERITY7 min read

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.

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

Answer Summary

CVE-2026-69192 is an IP address parsing inconsistency vulnerability (CWE-1025: Comparison Using Wrong Factors) in the Node.js `ip-address` package where the `Address4` decoder treats leading-zero octets as decimal while DNS resolvers interpret them as octal. This mismatch allows attackers to bypass IP-based trust boundaries and execute SSRF attacks. The fix upgrades `ip-address` to version 10.3.1, which corrects the octal interpretation to align with standard resolver behavior.

Vulnerability at a Glance

cweCWE-1025 (Comparison Using Wrong Factors), CWE-436 (Interpretation Conflict)
fixUpgrade `ip-address` from 10.2.0 to 10.3.1 to correct octal interpretation
riskServer-Side Request Forgery (SSRF), trust-boundary bypass, IP-based access control bypass
languageJavaScript/Node.js
root causeThe `ip-address` package's `Address4` class decoded leading-zero octets as decimal instead of octal, diverging from standard resolver behavior
vulnerabilityIP Address Parsing Inconsistency (Leading-Zero Octet Mismatch)

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

The Vulnerability Explained

In the CanvaLight plugin's dependency tree, a subtle but critical flaw existed in the ip-address npm package (version 10.2.0). The Address4 class—responsible for parsing IPv4 address strings—had a parsing inconsistency that could silently bypass IP-based trust boundaries.

The Core Problem:

The ip-address library decoded leading-zero octets as decimal numbers, while standard DNS resolvers and most operating systems decode them as octal. This created a dangerous divergence:

  • What the ip-address library saw: 010.0.0.1 → parsed as 10.0.0.1 (decimal interpretation of 010)
  • What DNS resolvers saw: 010.0.0.1 → parsed as 8.0.0.1 (octal interpretation of 010)

For applications using the ip-address library to validate or filter requests against IP whitelists, an attacker could craft a malicious request with a leading-zero IP address that would:
1. Pass validation checks in the application (because ip-address decoded it as expected)
2. Resolve to a different IP address at the DNS/resolver level (because resolvers use octal)
3. Reach an internal or restricted service that the application thought it was blocking

Why This Matters for CanvaLight

The CanvaLight plugin (in plugins/canvasight/package-lock.json) depends on ip-address for network operations. If CanvaLight uses this library to:
- Validate client IP addresses against a whitelist
- Construct URLs for internal service calls
- Parse proxy headers
- Implement IP-based rate limiting

...then an attacker could exploit the parsing mismatch to:
- Bypass IP-based access controls
- Perform Server-Side Request Forgery (SSRF) attacks against internal services
- Access restricted resources that should have been blocked

Real-World Attack Scenario

Imagine CanvaLight has a whitelist: ["192.168.1.100", "192.168.1.101"]. An attacker crafts a request with the IP 192.0168.1.100 (leading zero in the second octet):

GET /api/internal HTTP/1.1
X-Forwarded-For: 192.0168.1.100
  1. CanvaLight's validation (using ip-address 10.2.0):
    - Parses 192.0168.1.100192.8.1.100 (octal: 0168 = 8 in decimal... wait, no)
    - Actually: 192.0168.1.100192.168.1.100 (decimal interpretation of 0168 = 168)
    - ✅ Matches whitelist → Request allowed

  2. DNS resolver (standard behavior):
    - Parses 192.0168.1.100192.8.1.100 (octal: 0168 = 8)
    - ❌ Does not match whitelist → But resolver already resolved to 192.8.1.100
    - Request reaches 192.8.1.100 instead of the expected service

This is a trust-boundary bypass: the application and the resolver disagree on what IP address was requested.


The Fix

The fix upgrades the ip-address package from 10.2.0 to 10.3.1 in both package.json and package-lock.json:

Before (Vulnerable)

"node_modules/ip-address": {
  "version": "10.2.0",
  "resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-10.2.0.tgz",
  "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==",
  "license": "MIT",
  "peer": true,
  "engines": {

After (Fixed)

"node_modules/ip-address": {
  "version": "10.3.1",
  "resolved": "https://registry.npmmirror.com/ip-address/-/ip-address-10.3.1.tgz",
  "integrity": "sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g==",
  "license": "MIT",
  "peer": true,
  "engines": {

What Changed in Version 10.3.1

The ip-address 10.3.1 release corrected the Address4 parser to:

  1. Properly interpret leading-zero octets as octal, aligning with RFC standards and resolver behavior
  2. Validate that octal octets don't exceed 255 (since 0377 in octal = 255 in decimal, the maximum valid octet value)
  3. Reject invalid octal sequences that would produce out-of-range values

Now, when the parser encounters 010.0.0.1:
- It correctly interprets 010 as octal → 8 in decimal
- Result: 8.0.0.1 (matches DNS resolver behavior)
- Applications using this library now have consistent parsing across the entire stack

Why This Specific Fix Works

By upgrading to 10.3.1, the CanvaLight plugin now:
- ✅ Parses IP addresses consistently with DNS resolvers and OS-level network stacks
- ✅ Prevents attackers from crafting octal-encoded IPs to bypass validation
- ✅ Maintains backward compatibility for valid IP addresses (no leading zeros or standard decimal notation)
- ✅ Closes the trust-boundary gap that enabled SSRF attacks


Prevention & Best Practices

1. Always Validate IP Address Parsing Consistency

When using any IP parsing library, verify it matches your DNS resolver and network stack behavior:

// Test that your parser matches resolver behavior
const Address4 = require('ip-address').Address4;

const testCases = [
  '192.168.1.1',      // Standard
  '010.0.0.1',        // Octal (should parse to 8.0.0.1)
  '0377.0377.0377.0377' // Max octal (should parse to 255.255.255.255)
];

testCases.forEach(ip => {
  const parsed = new Address4(ip);
  console.log(`${ip} -> ${parsed.address}`);
  // Compare against: nslookup or dig output
});

2. Keep Dependencies Updated

IP parsing is security-critical. Subscribe to security advisories for your IP libraries:
- Use npm audit regularly
- Enable Dependabot or similar tools
- Review and apply patches for high-severity vulnerabilities

3. Never Trust IP-Based Access Controls Alone

Combine IP validation with other security measures:
- Use cryptographic authentication (JWT, OAuth, mTLS)
- Implement request signing
- Validate request origins through multiple channels

4. Use Canonical IP Representation

When storing or comparing IPs, normalize them first:

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

function normalizeIP(ipString) {
  try {
    const addr = new Address4(ipString);
    return addr.address; // Returns canonical form
  } catch (e) {
    throw new Error(`Invalid IP: ${ipString}`);
  }
}

// Now compare normalized forms
const whitelist = ['192.168.1.100', '192.168.1.101'].map(normalizeIP);
const clientIP = normalizeIP(req.headers['x-forwarded-for']);

5. Leverage Static Analysis

Use security scanners to detect known vulnerable versions:
- Trivy: Detects CVE-2026-69192 in package-lock.json
- npm audit: Built-in vulnerability detection
- Snyk: Continuous monitoring for dependency vulnerabilities

CWE References

  • CWE-1025: Comparison Using Wrong Factors (the parser and resolver use different interpretation rules)
  • CWE-436: Interpretation Conflict (same input, different meanings)
  • CWE-918: Server-Side Request Forgery (SSRF) - the consequence of the parsing mismatch

Key Takeaways

  • Leading-zero octets are octal, not decimal: The ip-address 10.2.0 library incorrectly parsed 010 as 10 instead of 8, breaking trust boundaries. Always verify your parser matches standard resolver behavior.

  • Trust-boundary misalignment is a security risk: When your application and your network stack disagree on what an IP address means, attackers can exploit the gap. This specific vulnerability allowed SSRF by making whitelisted IPs resolve to different addresses.

  • Upgrade ip-address to 10.3.1 or later: The fix corrects octal interpretation and closes the parsing inconsistency. If your project depends on ip-address, update immediately if you're on 10.2.0 or earlier.

  • Test IP parsing against real resolvers: Don't assume your library matches DNS behavior. Write tests that compare your parser's output to actual DNS resolution for edge cases like leading-zero octets.

  • IP-based security requires consistency across the stack: Whether you're validating whitelists, parsing proxy headers, or constructing internal URLs, ensure all components (application code, libraries, DNS, OS) interpret IP addresses the same way.


How Orbis AppSec Detected This

Source: Dependency manifest (plugins/canvasight/package-lock.json) containing ip-address version 10.2.0

Sink: Any code path in the CanvaLight plugin that uses Address4 to parse IP addresses for validation, filtering, or access control decisions

Missing Control: The ip-address 10.2.0 library lacked proper octal interpretation for leading-zero octets, creating a divergence from standard resolver behavior

CWE: CWE-1025 (Comparison Using Wrong Factors) and CWE-436 (Interpretation Conflict)

Fix: Upgrade ip-address from 10.2.0 to 10.3.1 to correct the Address4 parser's handling of leading-zero octets, aligning it with RFC standards and DNS resolver behavior

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 demonstrates a subtle but critical class of vulnerabilities: semantic divergence between components that should agree on data interpretation. When an application's IP parser and a DNS resolver interpret the same IP string differently, attackers can exploit the gap to bypass security controls and execute SSRF attacks.

The fix—upgrading ip-address to 10.3.1—restores consistency by correcting octal interpretation. However, the broader lesson is clear: always verify that your security-critical libraries match the behavior of the systems they interact with. For IP addresses, this means testing against real DNS resolvers. For other data types (URLs, file paths, JSON), the principle remains the same.

By keeping dependencies updated, validating parsing consistency, and combining IP-based controls with cryptographic authentication, you can prevent similar vulnerabilities in your own code.


References

Frequently Asked Questions

What is IP address parsing inconsistency?

It's a vulnerability where different systems parse the same IP address string differently—in this case, `10.2.0` parsed `010.0.0.1` as `10.0.0.1` (decimal) while DNS resolvers interpreted it as `8.0.0.1` (octal), causing trust-boundary misalignment.

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

Use well-maintained, actively audited IP parsing libraries; validate that your parser matches standard resolver behavior; never trust IP-based access controls without verifying parsing consistency; and keep dependencies updated regularly.

What CWE is IP address parsing inconsistency?

CWE-1025 (Comparison Using Wrong Factors) and CWE-436 (Interpretation Conflict) both apply—the core issue is that two components interpret the same input differently, breaking security assumptions.

Is updating the library enough to prevent SSRF through this vulnerability?

Yes, if the library update corrects the parsing behavior. However, you should also audit any code that relies on IP-based access controls to ensure it doesn't have compensating vulnerabilities.

Can static analysis detect this vulnerability?

Yes—scanners like Trivy detect known vulnerable versions of `ip-address`. However, detecting the *logic* of parsing inconsistency requires semantic analysis or fuzzing to compare output against expected resolver behavior.

View the Security Fix

Check out the pull request that fixed this vulnerability

View PR #3

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 Message-Level Raw Option Bypass happens in Node.js Nodemailer and how to fix it

A high-severity vulnerability in Nodemailer (GHSA-p6gq-j5cr-w38f) allowed attackers to bypass the `disableFileAccess` and `disableUrlAccess` security controls by using the message-level `raw` option, enabling arbitrary file reads and full-response SSRF in delivered emails. The fix upgrades Nodemailer from version 6.10.1 to 9.0.1, closing this bypass at the library level. This is especially critical for applications that allow any user-influenced content to flow into email composition.

high

How Unauthenticated Denial of Service happens in React Router and how to fix it

CVE-2026-55685 is a high-severity Denial of Service vulnerability in React Router's `@remix-run/server-runtime` that allows unauthenticated attackers to exhaust server resources by sending crafted requests to the manifest endpoint. The fix upgrades `react-router` from version 7.17.0 to 7.18.0, which tightens handling of untrusted input in route matching logic. Developers using any React Router 7.x application with server-side rendering should apply this patch immediately.