Skip to content
KitploitKITPLOIT
HerramientasBlog
Enviar
HerramientasBlog
Enviar

¡Herramientas de Hacking, PenTest y Ciberseguridad para tu Arsenal de Seguridad!

Kitploit es un directorio de herramientas de hacking, ciberseguridad y pentesting. Descubre las últimas actualizaciones de proyectos para encontrar vulnerabilidades, analizar sistemas, automatizar pruebas y fortalecer tu seguridad.

··Feeds·Contacto·Privacidad·© 2026 Kitploit

Directorio de Herramientas

Categorías

Ver todas las categorías
Loading categories
ip2 — Fork mantenido de node-ip con el aviso de SSRF no parcheado (CVE-2024-29415) corregido. | Kitploit
Herramientas/GitHubGitHub/bybravehq/ip2
Utilidades de Propósito GeneralAnálisis EstáticoAnálisis de VulnerabilidadesAuditoría de ConfiguraciónSeguridad WebSeguridad de Redes
GitHubbybravehq/ip2

ip2

Fork mantenido de node-ip con el aviso de SSRF no parcheado (CVE-2024-29415) corregido.

Ver Repositorio
hace 1 mesAún no revisado

Más Populares

Ver todos →

Descubre las herramientas más usadas por nuestra comunidad.

Explora todas las herramientas

Explora nuestra colección de herramientas

Ver todas las herramientas →
Compartir
Sitio web

@bybrave/ip2

CI npm

Fork mantenido de ip — utilidades de direcciones IP para Node.js — con el aviso SSRF sin parchear corregido.

El paquete original tiene ~38 millones de descargas/mes, sin lanzamiento desde febrero de 2024, y un aviso de gravedad ALTA (CVE-2024-29415 / GHSA-2p57-rm9w-gvfp) que afecta a todas las versiones publicadas y hace que npm audit falle en cada instalación. Este fork corrige la causa raíz en lugar de parchear expresiones regulares.

root@kitploit:~
npm install @bybrave/ip2
root@kitploit:~
// CommonJS — drop-in
const ip = require('@bybrave/ip2');

// ESM — named imports
import { isPrivate, isPublic, cidrSubnet } from '@bybrave/ip2';

// TypeScript types built in

La vulnerabilidad y cómo se corrige

Las funciones originales isPrivate() / isPublic() / isLoopback() ejecutaban expresiones regulares sobre la cadena de entrada sin procesar. Cualquier representación de una dirección que las expresiones regulares no anticiparan — octetos octales o hexadecimales, IPv4 abreviada, IPv6 sin comprimir — se clasificaba silenciosamente como pública:

root@kitploit:~
// original [email protected] — all of these are loopback/private, all reported PUBLIC:
ip.isPublic('127.1')            // true 💥
ip.isPublic('012.1.2.3')        // true 💥  (octal 10.1.2.3)
ip.isPublic('01200034567')      // true 💥  (integer 10.0.14.119)
ip.isPublic('000:0:0000::01')   // true 💥  (that's ::1)

Si esas respuestas protegen solicitudes salientes, eso es un agujero SSRF (CVE-2024-29415, corrección incompleta de CVE-2023-42282).

Este fork:

  1. Analiza primero, clasifica después. Cada función de clasificación analiza la dirección en bytes con un analizador estricto (misma gramática que net.isIP, más identificadores de zona IPv6). La clasificación se realiza sobre bytes, nunca sobre cadenas.
  2. Rechaza entradas ambiguas. Las representaciones no canónicas (127.1, 0x7f.1, 0177.0.0.1, 2130706433) lanzan una excepción en lugar de ser adivinadas. Fallo cerrado, no abierto. Si necesitas aceptar notaciones heredadas, normaliza explícitamente primero: ip.fromLong(ip.normalizeToLong(addr)).
  3. Cubre los registros completos de propósito especial de la IANA (IPv4, IPv6), no cuatro expresiones regulares. isPrivate() ahora significa "no alcanzable globalmente" — la misma convención que ipaddress de Python. Esto agrega CGNAT (100.64/10), TEST-NETs, benchmarking, multidifusión, reservado, ULA, rangos de documentación y más — ver la tabla a continuación.
  4. (mapeada a IPv4), (NAT64) y (6to4) son privadas/públicas según la dirección IPv4 que contienen.
root@kitploit:~
// @bybrave/ip2
ip.isPublic('127.1')             // throws Error: Invalid ip address: 127.1
ip.isPrivate('000:0:0000::01')   // true (parsed as ::1)
ip.isLoopback('::fFFf:127.0.0.1')// true
ip.isPublic('64:ff9b::8.8.8.8')  // true  (NAT64 of a public address)
ip.isPrivate('100.64.0.1')       // true  (CGNAT — original said public)

Todas las correcciones respecto a [email protected]

Migrando desde ip

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

La superficie de la API es la misma; las diferencias de comportamiento son las correcciones de seguridad y corrección — consulta los cambios incompatibles a continuación antes de actualizar.

Cambios incompatibles (v3)

Versión 3.0.0 porque la rigurosidad es la corrección — si alimentaste esta librería con cadenas no canónicas, v2 te daba respuestas incorrectas, no compatibles:

  • isPrivate / isPublic / isLoopback / toBuffer / toLong lanzan excepción en entradas mal formadas o no canónicas (octetos octales/hexadecimales, 127.1, cadenas de enteros). Usa normalizeToLong() primero si debes aceptar notaciones heredadas.
  • isLoopback('fe80::1') ahora es false (enlace-local ≠ loopback; sigue siendo isPrivate). isLoopback('::') ahora es false (no especificado ≠ loopback; sigue siendo isPrivate).
  • loopback('ipv6') devuelve en lugar de .

API

Todo lo que exporta el original, más isValid():

root@kitploit:~
ip.address('public', 'ipv6')          // address of a network interface
ip.isPrivate('10.0.0.1')              // true — not globally reachable
ip.isPublic('8.8.8.8')                // true
ip.isLoopback('127.8.8.8')            // true
ip.isValid('300.1.2.3')               // false (never throws)
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 (lenient, -1 on error)

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-mapped handled)

Rangos tratados como privados (no alcanzables globalmente)

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 (incl. broadcast).

IPv6: ::/96 (sin especificar, loopback, compatible con IPv4), 64:ff9b:1::/48, 100::/64, 2001::/23, 2001:db8::/32, 3fff::/20, 5f00::/16, fc00::/7, fe80::/10, fec0::/10, ff00::/8. Los rangos de transición ::ffff:0:0/96, 64:ff9b::/96 y 2002::/16 siguen su dirección IPv4 incrustada.

Soporte

Si este paquete te ahorra tiempo, puedes apoyar el mantenimiento:

Ko-fi Bitcoin

Bitcoin (BTC): bc1q37557q5jpeaxqydzwvf3jgj7zhnfpn2td3q40q

Créditos y licencia

MIT. Basado en node-ip por Fedor Indutny.

Descargar herramienta
Clasifica las direcciones de transición por su IPv4 incrustada.
::ffff:a.b.c.d
64:ff9b::a.b.c.d
2002:xxxx:xxxx::
CorregidoProblema original
CVE-2024-29415 / GHSA-2p57-rm9w-gvfp — SSRF a través de direcciones no canónicas#136, #150, #153, #158
isPrivate() omite CGNAT, TEST-NETs, benchmarking, multidifusión, reservado, rangos de documentación—
cidrSubnet(...).contains() devuelve false para direcciones IPv6 mapeadas a IPv4#104
isV6Format() devuelve true para direcciones IPv4#67
isV4Format() acepta octetos ≥ 256#105
address('public') devolvía direcciones privadas y viceversa (el filtro estaba invertido)—
loopback('ipv6') devolvía fe80::1, que es enlace-local, no loopback → ahora ::1—
cidr()/cidrSubnet() producían silenciosamente basura para longitudes de prefijo inválidas (/33, /x) → ahora lanzan excepción—
address(name) fallaba con TypeError para nombres de interfaz desconocidos → ahora devuelve undefined—
Tipos TypeScript incorporados (no se necesita @types/ip), exportaciones con nombre ESM—
'::1'
'fe80::1'
  • isPrivate() devuelve true para más rangos (CGNAT, TEST-NETs, multidifusión, …) — ahora significa "no alcanzable globalmente".
  • address('public') ahora devuelve direcciones públicas realmente. Si confiabas en el comportamiento invertido para obtener una dirección LAN, usa address('private') — eso es lo que te estaba dando.
  • Node.js ≥ 18.