Skip to content
KitploitKITPLOIT
工具博客
提交
工具博客
提交

黑客、渗透测试和网络安全工具,武装您的安全武器库!

Kitploit 是一个黑客、网络安全和渗透测试工具的目录。发现最新的项目更新,查找漏洞、分析系统、自动化测试并加强你的安全。

··订阅源·联系·隐私·© 2026 Kitploit

工具目录

分类

查看所有分类
Loading categories
ip2 — node-ip的维护分支,修复了未修补的SSRF安全公告(CVE-2024-29415) | Kitploit
工具/GitHubGitHub/bybravehq/ip2
通用工具静态分析漏洞分析配置审计Web安全网络安全
GitHubbybravehq/ip2

ip2

node-ip的维护分支,修复了未修补的SSRF安全公告(CVE-2024-29415)

查看仓库
42个月前尚未审核

最受欢迎

查看全部 →

发现我们社区最常用的工具。

探索所有工具

浏览我们的工具集合

查看所有工具 →
分享
网站

@bybrave/ip2

CI npm

ip(原仓库)的维护分支——Node.js 的 IP 地址工具库——修复了未修补的 SSRF 安全公告。

原包每月约 3800 万次下载,自 2024 年 2 月以来未发布新版本,并且有一个影响每个已发布版本的高严重性安全公告(CVE-2024-29415 / GHSA-2p57-rm9w-gvfp),导致每次安装时 npm audit 失败。本分支修复了根本原因,而非修补正则表达式。

root@kitploit:~
npm install @bybrave/ip2
root@kitploit:~
// CommonJS — 可直接替换
const ip = require('@bybrave/ip2');

// ESM — 具名导入
import { isPrivate, isPublic, cidrSubnet } from '@bybrave/ip2';

// 内置 TypeScript 类型

漏洞及其修复方式

原始的 isPrivate() / isPublic() / isLoopback() 对原始输入字符串运行正则表达式。任何正则表达式未预见的地址拼写方式(八进制或十六进制字节、缩写 IPv4、未压缩 IPv6)都会被静默归类为公网地址:

root@kitploit:~
// 原始 [email protected] — 以下全是回环/私有地址,但全部报告为公网:
ip.isPublic('127.1')            // true 💥
ip.isPublic('012.1.2.3')        // true 💥  (八进制 10.1.2.3)
ip.isPublic('01200034567')      // true 💥  (整数 10.0.14.119)
ip.isPublic('000:0:0000::01')   // true 💥  (即 ::1)

如果这些判断结果用于保护出站请求,就构成了 SSRF 漏洞(CVE-2024-29415,CVE-2023-42282 的不完全修复)。

本分支:

  1. 先解析,再分类。 每个分类函数都使用严格的解析器(与 net.isIP 相同的语法,外加 IPv6 区域 ID)将地址解析为字节。分类基于字节进行,绝不基于字符串。
  2. 拒绝歧义输入。 非规范拼写(如 127.1、0x7f.1、0177.0.0.1、2130706433)抛出异常而非猜测。失败关闭而非开放。如果需要接受遗留表示法,请先显式标准化:ip.fromLong(ip.normalizeToLong(addr))。
  3. 覆盖完整的 IANA 特殊用途注册表(IPv4、IPv6),而非四个正则表达式。isPrivate() 现在表示“全局不可达”——与 Python 的 ipaddress 约定相同。这新增了 CGNAT(100.64/10)、TEST-NET、基准测试、组播、保留、ULA、文档范围等——见下方表格。
  4. 根据嵌入的 IPv4 地址对过渡地址进行分类。 ::ffff:a.b.c.d(v4 映射)、64:ff9b::a.b.c.d(NAT64)和 2002:xxxx:xxxx::(6to4)根据其内部的 IPv4 地址判断私有/公网。
root@kitploit:~
// @bybrave/ip2
ip.isPublic('127.1')             // 抛出 Error: Invalid ip address: 127.1
ip.isPrivate('000:0:0000::01')   // true (解析为 ::1)
ip.isLoopback('::fFFf:127.0.0.1')// true
ip.isPublic('64:ff9b::8.8.8.8')  // true  (公网地址的 NAT64)
ip.isPrivate('100.64.0.1')       // true  (CGNAT——原版报告为公网)

对 [email protected] 的所有修复

从 ip 迁移

root@kitploit:~
- const ip = require('ip');
+ const ip = require('@bybrave/ip2');

API 表面相同;行为差异在于安全性和正确性修复——升级前请查看下方的破坏性变更。

破坏性变更(v3)

版本号 3.0.0 是因为严格性本身就是修复——如果您向此库提供非规范字符串,v2 会给出错误答案,而非兼容的答案:

  • isPrivate / isPublic / isLoopback / toBuffer / toLong 在遇到格式错误或非规范输入(八进制/十六进制字节、127.1、整数字符串)时抛出异常。如果必须接受遗留表示法,请先使用 normalizeToLong()。
  • isLoopback('fe80::1') 现在返回 false(链路本地 ≠ 回环;但仍是 isPrivate)。isLoopback('::') 现在返回 false(未指定 ≠ 回环;但仍是 isPrivate)。
  • loopback('ipv6') 返回 '::1' 而非 。

API

原始包导出的所有内容,外加 isValid():

root@kitploit:~
ip.address('public', 'ipv6')          // 网络接口的地址
ip.isPrivate('10.0.0.1')              // true — 全局不可达
ip.isPublic('8.8.8.8')                // true
ip.isLoopback('127.8.8.8')            // true
ip.isValid('300.1.2.3')               // false(从不抛出异常)
ip.isV4Format('192.168.0.1')          // true
ip.isV6Format('2001:db8::1')          // true
ip.isEqual('::ffff:7f00:1', '127.0.0.1') // true

ip.toBuffer('127.0.0.1')              // Buffer([127, 0, 0, 1])
ip.toString(buf, offset, length)      // '127.0.0.1'
ip.toLong('127.0.0.1')                // 2130706433
ip.fromLong(2130706433)               // '127.0.0.1'
ip.normalizeToLong('127.1')           // 2130706433(宽松模式,出错返回 -1)

ip.fromPrefixLen(24)                  // '255.255.255.0'
ip.mask('192.168.1.134', '255.255.255.0') // '192.168.1.0'
ip.cidr('192.168.1.134/26')           // '192.168.1.128'
ip.not('255.255.255.0')               // '0.0.0.255'
ip.or('0.0.0.255', '192.168.1.10')    // '192.168.1.255'

const s = ip.cidrSubnet('192.168.1.134/26')
s.networkAddress                      // '192.168.1.128'
s.firstAddress                        // '192.168.1.129'
s.lastAddress                         // '192.168.1.190'
s.broadcastAddress                    // '192.168.1.191'
s.subnetMaskLength                    // 26
s.numHosts                            // 62
s.contains('::ffff:192.168.1.180')    // true(正确处理 v4 映射)

视为私有(全局不可达)的范围

IPv4: 0.0.0.0/8、10.0.0.0/8、100.64.0.0/10(CGNAT)、127.0.0.0/8、169.254.0.0/16、172.16.0.0/12、192.0.0.0/24、192.0.2.0/24、192.88.99.0/24、192.168.0.0/16、198.18.0.0/15、198.51.100.0/24、203.0.113.0/24、224.0.0.0/4、240.0.0.0/4(包括广播)。

IPv6: ::/96(未指定、回环、v4 兼容)、64:ff9b:1::/48、100::/64、2001::/23、2001:db8::/32、3fff::/20、5f00::/16、fc00::/7、fe80::/10、fec0::/10、ff00::/8。过渡范围 ::ffff:0:0/96、64:ff9b::/96 和 2002::/16 遵循其嵌入的 IPv4 地址。

支持

如果此包为您节省了时间,您可以支持维护工作:

Ko-fi Bitcoin

比特币(BTC):bc1q37557q5jpeaxqydzwvf3jgj7zhnfpn2td3q40q

版权与许可证

MIT。基于 Fedor Indutny 的 node-ip。

下载工具
修复内容原始问题
CVE-2024-29415 / GHSA-2p57-rm9w-gvfp — 通过非规范地址的 SSRF#136、#150、#153、#158
isPrivate() 遗漏了 CGNAT、TEST-NET、基准测试、组播、保留、文档范围—
cidrSubnet(...).contains() 对 IPv4 映射的 IPv6 地址返回 false#104
isV6Format() 对 IPv4 地址返回 true#67
isV4Format() 接受 ≥ 256 的字节#105
address('public') 返回了私有地址,反之亦然(过滤器反转)—
loopback('ipv6') 返回 fe80::1,这是链路本地地址,不是回环地址 → 现在返回 ::1—
cidr()/cidrSubnet() 对无效前缀长度(/33、/x)静默产生垃圾结果 → 现在抛出异常—
address(name) 对未知接口名称抛出 TypeError → 现在返回 undefined—
内置 TypeScript 类型(无需 @types/ip)、ESM 具名导出—
'fe80::1'
  • isPrivate() 对更多范围返回 true(CGNAT、TEST-NET、组播等)——现在它表示“全局不可达”。
  • address('public') 现在实际上返回公网地址。如果您依赖反转行为来获取局域网地址,请使用 address('private')——那正是之前它返回给您的。
  • Node.js ≥ 18。