Skip to content
KitploitKITPLOIT
HerramientasExploitsBlog
Log in
Enviar
HerramientasExploitsBlog
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.

FeedsContactoPrivacidad© 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
33hace 10 díasAún no revisado
Sitio web

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

@bybrave/ip2

CI npm

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

El paquete original tiene ~38M de descargas/mes, ninguna versión desde febrero de 2024, y un aviso de severidad 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.

npm install @bybrave/ip2
// 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 forma de escribir una dirección que las expresiones regulares no anticiparan — octetos octales o hexadecimales, IPv4 abreviada, IPv6 sin comprimir — se clasificaba silenciosamente como pública:

// 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 de SSRF (CVE-2024-29415, corrección incompleta de CVE-2023-42282).

Este fork:

  1. Primero analiza, después clasifica. Cada función de clasificación analiza la dirección en bytes con un analizador estricto (la misma gramática que net.isIP, más los IDs de zona IPv6). La clasificación se ejecuta sobre bytes, nunca sobre cadenas.
  2. Rechaza entradas ambiguas. Las formas no canónicas (127.1, 0x7f.1, 0177.0.0.1, 2130706433) lanzan una excepción en lugar de adivinar. Falla cerrado, no abierto. Si necesitas aceptar notaciones heredadas, normaliza explícitamente primero: ip.fromLong(ip.normalizeToLong(addr)).
  3. Cubre los registros completos de propósitos especiales de la IANA (IPv4, IPv6), no cuatro expresiones regulares. isPrivate() ahora significa "no alcanzable globalmente" — la misma convención que ipaddress de Python. Eso añade CGNAT (100.64/10), TEST-NETs, benchmarking, multicast, reservadas, ULA, rangos de documentación y más — consulta la tabla a continuación.
  4. Clasifica las direcciones de transición por su IPv4 incrustada. ::ffff:a.b.c.d (v4-mapeada), 64:ff9b::a.b.c.d (NAT64) y 2002:xxxx:xxxx:: (6to4) son privadas/públicas según la dirección IPv4 que contienen.
// @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 sobre [email protected]

CorregidoProblema original
CVE-2024-29415 / GHSA-2p57-rm9w-gvfp — SSRF mediante direcciones no canónicas#136, #150, #153, #158
isPrivate() omite CGNAT, TEST-NETs, benchmarking, multicast, reservadas, rangos de documentación—
cidrSubnet(...).contains() devuelve false para direcciones IPv6 mapeadas desde 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 link-local, no loopback → ahora ::1—
cidr()/cidrSubnet() producían basura silenciosamente 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—
cidrSubnet()/subnet() daban respuestas incorrectas para IPv6 (/48 contenía un /48 vecino) → aritmética real de subredes IPv6#89, #110
El empaquetado para el navegador fallaba en os (webpack 5) → el campo browser lo redirige#127, #132
Tipos de TypeScript integrados (no se necesita @types/ip), exportaciones nombradas ESM—

Migrar desde ip

- 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 disruptivos a continuación antes de actualizar.

Cambios disruptivos (v3)

Versión 3.0.0 porque el rigor es la corrección — si le pasabas a esta biblioteca cadenas no canónicas, la v2 te estaba dando respuestas incorrectas, no compatibles:

  • isPrivate / isPublic / isLoopback / toBuffer / toLong lanzan excepción ante entradas malformadas 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 (link-local ≠ loopback; sigue siendo isPrivate). isLoopback('::') ahora es false (no especificada ≠ loopback; sigue siendo isPrivate).
  • loopback('ipv6') devuelve '::1' en lugar de 'fe80::1'.
  • isPrivate() devuelve true para más rangos (CGNAT, TEST-NETs, multicast, …) — ahora significa "no alcanzable globalmente".
  • address('public') ahora devuelve realmente direcciones públicas. Si dependías del comportamiento invertido para obtener una dirección LAN, usa address('private') — eso es lo que te estaba dando.
  • Node.js ≥ 18.

API

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

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'
Descargar herramienta