Skip to content
KitploitKITPLOIT
StrumentiExploitsBlog
Log in
Invia
StrumentiExploitsBlog
Invia

Strumenti di Hacking, PenTest e Cybersecurity per il tuo Arsenale di Sicurezza!

Kitploit è una directory di strumenti di hacking, cybersecurity e pentesting. Scopri gli ultimi aggiornamenti dei progetti per trovare vulnerabilità, analizzare sistemi, automatizzare i test e rafforzare la tua sicurezza.

FeedContattoPrivacy© 2026 Kitploit

Directory degli strumenti

Categorie

Vedi tutte le categorie
Loading categories
ip2 — Fork mantenuto di node-ip in cui è stato risolto l'avviso SSRF senza patch (CVE-2024-29415) | Kitploit
Strumenti/GitHubGitHub/bybravehq/ip2
Utilità GenericheAnalisi StaticaAnalisi delle VulnerabilitàAudit di ConfigurazioneSicurezza WebSicurezza di Rete
GitHubbybravehq/ip2

ip2

Fork mantenuto di node-ip in cui è stato risolto l'avviso SSRF senza patch (CVE-2024-29415)

Vedi Repository
3310 giorni faNon ancora revisionato
Sito web

Più Popolari

Vedi tutti →

Scopri gli strumenti più utilizzati dalla nostra community.

Esplora tutti gli strumenti

Sfoglia la nostra collezione di strumenti

Vedi tutti gli strumenti →
Condividi

@bybrave/ip2

CI npm

Fork mantenuto di ip — utilità per indirizzi IP per Node.js — con la vulnerabilità SSRF non corretta risolta.

Il pacchetto originale ha ~38M download/mese, nessuna release da febbraio 2024, e un advisory di gravità HIGH (CVE-2024-29415 / GHSA-2p57-rm9w-gvfp) che interessa ogni versione pubblicata e fa fallire npm audit a ogni installazione. Questo fork corregge la causa alla radice invece di rattoppare le regex.

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 vulnerabilità, e come è stata corretta

Le funzioni originali isPrivate() / isPublic() / isLoopback() eseguivano regex sulla stringa di input grezza. Qualsiasi grafia di un indirizzo che le regex non prevedevano — ottetti ottali o esadecimali, IPv4 abbreviato, IPv6 non compresso — veniva silenziosamente classificata come pubblica:

// 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)

Se queste risposte proteggono richieste in uscita, si tratta di una falla SSRF (CVE-2024-29415, correzione incompleta di CVE-2023-42282).

Questo fork:

  1. Prima analizza, poi classifica. Ogni funzione di classificazione analizza l'indirizzo in byte con un parser rigoroso (stessa grammatica di net.isIP, più gli zone ID IPv6). La classificazione opera sui byte, mai sulle stringhe.
  2. Rifiuta input ambigui. Le grafie non canoniche (127.1, 0x7f.1, 0177.0.0.1, 2130706433) generano un'eccezione invece di essere indovinate. Fail closed, non open. Se devi accettare notazioni legacy, normalizza esplicitamente prima: ip.fromLong(ip.normalizeToLong(addr)).
  3. Copre l'intero registro IANA degli indirizzi special-purpose (IPv4, IPv6), non quattro regex. isPrivate() ora significa "non raggiungibile globalmente" — la stessa convenzione di ipaddress di Python. Questo aggiunge CGNAT (100.64/10), TEST-NET, benchmarking, multicast, reserved, ULA, range di documentazione e altro — vedi la tabella sotto.
  4. Classifica gli indirizzi di transizione in base al loro IPv4 incorporato. ::ffff:a.b.c.d (v4-mapped), 64:ff9b::a.b.c.d (NAT64) e 2002:xxxx:xxxx:: (6to4) sono privati/pubblici in base all'indirizzo IPv4 al loro interno.
// @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)

Tutte le correzioni rispetto a [email protected]

CorrettoProblema originale
CVE-2024-29415 / GHSA-2p57-rm9w-gvfp — SSRF tramite indirizzi non canonici#136, #150, #153, #158
isPrivate() non rileva CGNAT, TEST-NET, benchmarking, multicast, reserved, range di documentazione—
cidrSubnet(...).contains() restituisce false per indirizzi IPv6 v4-mapped#104
isV6Format() restituisce true per indirizzi IPv4#67
isV4Format() accetta ottetti ≥ 256#105
address('public') restituiva indirizzi privati e viceversa (filtro invertito)—
loopback('ipv6') restituiva fe80::1, che è link-local, non loopback → ora ::1—
cidr()/cidrSubnet() producevano silenziosamente risultati errati per lunghezze di prefisso non valide (/33, /x) → ora generano un'eccezione—
address(name) andava in crash con TypeError per nomi di interfaccia sconosciuti → ora restituisce undefined—
cidrSubnet()/subnet() davano risposte errate per IPv6 (/48 conteneva un /48 adiacente) → vera aritmetica di subnet IPv6#89, #110
Il bundling per il browser falliva su os (webpack 5) → il campo browser lo mappa altrove#127, #132
Tipi TypeScript integrati (nessun @types/ip necessario), export nominati ESM—

Migrazione da ip

- const ip = require('ip');
+ const ip = require('@bybrave/ip2');

La superficie API è la stessa; le differenze di comportamento sono le correzioni di sicurezza e correttezza — vedi le breaking changes sotto prima di aggiornare.

Breaking changes (v3)

Versione 3.0.0 perché il rigore è la correzione — se passavi a questa libreria stringhe non canoniche, la v2 ti dava risposte sbagliate, non compatibili:

  • isPrivate / isPublic / isLoopback / toBuffer / toLong generano un'eccezione su input malformati o non canonici (ottetti ottali/esadecimali, 127.1, stringhe intere). Usa prima normalizeToLong() se devi accettare notazioni legacy.
  • isLoopback('fe80::1') ora è false (link-local ≠ loopback; resta comunque isPrivate). isLoopback('::') ora è false (unspecified ≠ loopback; resta comunque isPrivate).
  • loopback('ipv6') restituisce '::1' invece di 'fe80::1'.
  • isPrivate() restituisce true per più range (CGNAT, TEST-NET, multicast, …) — ora significa "non raggiungibile globalmente".
  • address('public') ora restituisce effettivamente indirizzi pubblici. Se facevi affidamento sul comportamento invertito per ottenere un indirizzo LAN, usa address('private') — era quello che ti restituiva.
  • Node.js ≥ 18.

API

Tutto ciò che esporta l'originale, più 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'
Scarica lo strumento