Skip to content

fix: address SSRF bypass patterns in isPrivate/isPublic (CVE-2024-29415)#166

Open
abhu85 wants to merge 2 commits intoindutny:mainfrom
abhu85:fix/ssrf-bypass-cve-2024-29415
Open

fix: address SSRF bypass patterns in isPrivate/isPublic (CVE-2024-29415)#166
abhu85 wants to merge 2 commits intoindutny:mainfrom
abhu85:fix/ssrf-bypass-cve-2024-29415

Conversation

@abhu85
Copy link

@abhu85 abhu85 commented Feb 26, 2026

Summary

This PR fixes multiple SSRF bypass vulnerabilities in isPublic() and isPrivate() that allow attackers to access internal resources by using non-standard IP address formats.

CVE: CVE-2024-29415, CVE-2025-59436
Severity: High (CVSS 8.1)
Impact: ~40 million weekly downloads

Bypass Patterns Fixed

Pattern Example Resolves To Issue
Null route 0 0.0.0.0 #160
32-bit octal 017700000001 127.0.0.1 #162
Short-form 127.1, 127.0.1 127.0.0.1 #150
Octal notation 0177.0.0.1 127.0.0.1 #150
Hex notation 0x7f.0.0.1 127.0.0.1 #150
IPv6 expanded 0:0:0:0:0:0:0:1 ::1 #150
IPv6-mapped hex ::ffff:7f00:1 127.0.0.1 #122

Attack Scenario

// Typical vulnerable application
function makeRequest(userUrl) {
    const hostname = new URL(userUrl).hostname;
    
    if (ip.isPublic(hostname)) {
        return fetch(userUrl); // BYPASSED!
    }
    throw new Error("Private IP blocked");
}

// These attacks succeed without this fix:
makeRequest("http://0:3000/admin");           // Null route
makeRequest("http://017700000001:3000/admin"); // 32-bit octal
makeRequest("http://127.1:3000/admin");        // Short-form

Changes

lib/ip.js

  • isLoopback(): Now normalizes IPv4 addresses using normalizeToLong() before checking, correctly handling all numeric formats
  • isPrivate(): Added check for 0.0.0.0/8 range (null route/reserved)
  • _extractIPv4FromMapped(): New helper to extract IPv4 from IPv6-mapped addresses (both dot and hex notation)
  • _isIPv6Loopback(): New helper for expanded IPv6 loopback detection

test/api-test.js

  • Added comprehensive test suite for all SSRF bypass patterns
  • Tests document security-critical behavior
  • Covers edge cases and regression scenarios

Backward Compatibility

This fix is backward compatible:

  • No breaking API changes
  • No new dependencies
  • Works with existing Node.js versions supported by this package
  • Only changes classification of addresses that were incorrectly identified

Testing

npm test

All existing tests pass, plus 40+ new security-focused tests.

Related Issues

Why Not PR #144?

PR #144 takes a more aggressive approach requiring Node.js 15+ and rejecting non-standard formats entirely. This PR:

  • Maintains backward compatibility
  • Works with older Node.js versions
  • Correctly classifies non-standard formats instead of rejecting them
  • Can be released as a patch version (2.0.2)

References

This commit fixes multiple SSRF bypass patterns that allow attackers to
bypass isPublic()/isPrivate() checks:

1. Null route "0" - now correctly identified as private (0.0.0.0)
2. 32-bit octal format "017700000001" - now correctly identified as loopback
3. IPv6 loopback variations (::1, 0:0:0:0:0:0:0:1) - improved detection
4. IPv6-mapped IPv4 loopback in hex (::ffff:7f00:1) - now detected
5. Short-form IPs (127.1, 127.0.1) - already handled, added tests

Changes:
- isLoopback() now normalizes IPv4 addresses before checking
- isPrivate() now checks for 0.0.0.0/8 range (null route)
- Added helper to extract IPv4 from IPv6-mapped addresses
- Comprehensive test coverage for all bypass patterns

Fixes: CVE-2024-29415
Refs: indutny#150, indutny#158, indutny#160, indutny#162
Add test cases for all known SSRF bypass patterns:
- Null route "0" (Issue indutny#160)
- 32-bit octal format "017700000001" (Issue indutny#162, CVE-2025-59436)
- Short-form IPs (127.1, 127.0.1)
- IPv6 loopback variations
- IPv6-mapped IPv4 addresses in hex notation
- Standard private range verification

These tests document the security-critical behavior and ensure
bypass patterns are correctly identified as private/loopback.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

1 participant