Skip to content

Request: New advisory for SSRF bypass in ip (npm) package via isV6Format() regex misclassification #7698

@MustafaRabbah

Description

@MustafaRabbah

Summary

I would like to request a GitHub Security Advisory entry for a vulnerability I discovered in the ip npm package.

Package

Vulnerability class

Server-Side Request Forgery (SSRF) Bypass

Suggested CWE

  • CWE-918: Server-Side Request Forgery (SSRF)

Title

SSRF bypass in ip.isPrivate() via isV6Format() regex misclassification

Description

A vulnerability exists in the ip npm package version 2.0.1 (the latest and final release). The isV6Format() function uses a flawed regular expression that incorrectly classifies private IPv4 addresses with appended hex data as valid IPv6 addresses. This causes isPrivate() to return false for private IP addresses when an attacker appends a colon followed by arbitrary hexadecimal characters.
The vulnerable regex at lib/ip.js:86:

const ipv6Regex = /^(::)?(((\d{1,3}\.){3}(\d{1,3}){1})?([0-9a-f]){0,4}:{0,2}){1,8}(::)?$/i;

This regex matches embedded IPv4 addresses followed by :hex, causing inputs like 10.0.0.1:8080 or 192.168.1.1:cafe to be classified as IPv6. When isPrivate() detects IPv6 format, it skips normalizeToLong() and tests the raw string against private-range regexes — which fail due to the appended suffix, resulting in false.

Proof of Concept

const ip = require('ip');
console.log(ip.isPrivate('10.0.0.1'));        // true  (correct)
console.log(ip.isPrivate('10.0.0.1:8080'));   // false (BYPASS!)
console.log(ip.isPrivate('10.0.0.1:dead'));   // false (BYPASS!)
console.log(ip.isPrivate('192.168.1.1:cafe'));  // false (BYPASS!)
console.log(ip.isPrivate('169.254.169.254:abc')); // false (BYPASS!)

Affected ranges

All private IPv4 ranges: 10.x.x.x, 192.168.x.x, 172.16-31.x.x, 169.254.x.x
Not affected: 127.x.x.x (caught by isLoopback() before isV6Format())

CVSS

CVSS 3.1 Score: 9.1 (Critical)
Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

Impact

An attacker can bypass SSRF protection in any application that uses ip.isPrivate() as a security guard to block requests to internal networks. By simply appending :hex to a private IP address, the attacker can make the target server send HTTP requests to internal services (databases, admin panels, cloud metadata endpoints, etc.). The library has ~10M weekly downloads and ~3,500 dependent packages on npm.

Affected versions

  • Vulnerable: >= 0.0.0, <= 2.0.1
  • Patched: none (no fix available, repository archived, package no longer maintained)

References

Disclosure attempts

The repository indutny/node-ip has no SECURITY.md, no private vulnerability reporting enabled, and is archived with no recent maintainer activity. No response was received from maintainers.

Reporter

Mustafa Rabbah

I am happy to provide any additional technical details required, including full PoC, test results, and reproduction material. If preferred, I can also submit a pull request to this repository with the OSV-formatted advisory file.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions