Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

الخلاصاتاتصالالخصوصية© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
ip2 — فرع مُحافظ عليه من node-ip مع إصلاح الاستشارة غير المُصححة لـ SSRF (CVE-2024-29415) | Kitploit
أدوات/GitHubGitHub/bybravehq/ip2
أدوات عامةالتحليل الثابتتحليل الثغرات الأمنيةتدقيق التكوينأمن الويبأمن الشبكات
GitHubbybravehq/ip2

ip2

فرع مُحافظ عليه من node-ip مع إصلاح الاستشارة غير المُصححة لـ SSRF (CVE-2024-29415)

عرض المستودع
33منذ 10 أياملم تتم المراجعة بعد
الموقع الإلكتروني

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

@bybrave/ip2

CI npm

نسخة مُصانة (fork) من ip — أدوات عناوين IP لـ Node.js — مع إصلاح ثغرة SSRF غير المُرقَّعة.

الحزمة الأصلية لديها ~38 مليون تنزيل شهريًا، ولا يوجد إصدار منذ فبراير 2024، ولديها تنبيه أمني بدرجة HIGH (CVE-2024-29415 / GHSA-2p57-rm9w-gvfp) يؤثر على كل إصدار منشور ويجعل npm audit يفشل عند كل تثبيت. هذه النسخة المُصانة تصلح السبب الجذري بدلًا من ترقيع التعبيرات النمطية (regexes).

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

الثغرة، وكيفية إصلاحها

الدوال الأصلية isPrivate() / isPublic() / isLoopback() كانت تُشغّل تعبيرات نمطية على سلسلة الإدخال الخام. أي كتابة لعنوان لم تتوقعها التعبيرات النمطية — بايتات ثمانية أو سادس عشرية، IPv4 مختصر، IPv6 غير مضغوط — كانت تُصنَّف بصمت على أنها عامة:

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

إذا كانت هذه الإجابات تحمي الطلبات الصادرة، فهذه ثغرة SSRF (CVE-2024-29415، إصلاح غير مكتمل لـ CVE-2023-42282).

هذه النسخة المُصانة:

  1. تُحلّل أولًا، ثم تُصنّف. كل دالة تصنيف تُحلّل العنوان إلى بايتات باستخدام محلّل صارم (نفس قواعد net.isIP، بالإضافة إلى معرّفات نطاق IPv6). يجري التصنيف على البايتات، وليس على السلاسل النصية أبدًا.
  2. ترفض الإدخال الغامض. الكتابات غير القياسية (127.1، 0x7f.1، 0177.0.0.1، 2130706433) تُطلق خطأً بدلًا من التخمين. الفشل مغلق، وليس مفتوحًا. إذا كنت بحاجة لقبول الصيغ القديمة، طبّعها صراحةً أولًا: ip.fromLong(ip.normalizeToLong(addr)).
  3. تغطي سجلات IANA كاملة للأغراض الخاصة (IPv4، IPv6)، وليس أربعة تعبيرات نمطية. أصبح isPrivate() يعني "غير قابل للوصول عالميًا" — نفس اصطلاح ipaddress في Python. يضيف ذلك CGNAT (100.64/10)، وTEST-NETs، والقياس المرجعي (benchmarking)، والبث المتعدد (multicast)، والمحجوز (reserved)، وULA، ونطاقات التوثيق والمزيد — انظر الجدول أدناه.
  4. تُصنّف عناوين الانتقال حسب IPv4 المضمّن فيها. ::ffff:a.b.c.d (v4-mapped)، و64:ff9b::a.b.c.d (NAT64)، و2002:xxxx:xxxx:: (6to4) تُعدّ خاصة/عامة وفقًا لعنوان IPv4 الموجود داخلها.
// @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)

كل الإصلاحات مقارنةً بـ [email protected]

تم إصلاحهالمشكلة الأصلية
CVE-2024-29415 / GHSA-2p57-rm9w-gvfp — SSRF عبر عناوين غير قياسية#136، #150، #153، #158
isPrivate() تُفوّت CGNAT، وTEST-NETs، والقياس المرجعي، والبث المتعدد، والمحجوز، ونطاقات التوثيق—
cidrSubnet(...).contains() تُعيد false لعناوين IPv6 المُعبَّر عنها كـ IPv4-mapped#104
isV6Format() تُعيد true لعناوين IPv4#67
isV4Format() تقبل بايتات ≥ 256#105
address('public') كانت تُعيد عناوين خاصة والعكس صحيح (المرشّح كان معكوسًا)—
loopback('ipv6') كانت تُعيد fe80::1، وهو link-local وليس loopback → الآن ::1—
cidr()/cidrSubnet() كانتا تُنتجان بيانات تالفة بصمت لأطوال بادئة غير صالحة (/33، /x) → الآن تُطلقان خطأً—
address(name) كانت تنهار بخطأ TypeError لأسماء واجهات غير معروفة → الآن تُعيد undefined—
cidrSubnet()/subnet() كانتا تُعطيان إجابات خاطئة لـ IPv6 (/48 كان يحتوي على /48 مجاور) → حساب شبكات IPv6 حقيقي#89، #110
تجميع الحزمة للمتصفح كان يفشل على os (webpack 5) → حقل browser يعيد توجيهه بعيدًا#127، #132
أنواع TypeScript مدمجة (لا حاجة لـ @types/ip)، وتصديرات ESM المُسمّاة—

الترحيل من ip

- 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 (link-local ≠ loopback؛ لكنها تبقى isPrivate). isLoopback('::') أصبحت الآن false (غير محدد ≠ loopback؛ لكنها تبقى isPrivate).
  • loopback('ipv6') تُعيد '::1' بدلًا من 'fe80::1'.
  • isPrivate() تُعيد true لنطاقات أكثر (CGNAT، TEST-NETs، البث المتعدد، …) — أصبحت تعني "غير قابل للوصول عالميًا".
  • address('public') تُعيد الآن عناوين عامة فعلًا. إذا كنت تعتمد على السلوك المعكوس للحصول على عنوان LAN، استخدم address('private') — فهذا ما كانت تُعطيه لك.
  • Node.js ≥ 18.

API

كل ما تُصدّره النسخة الأصلية، بالإضافة إلى 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'

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)

const s6 = ip.cidrSubnet('2001:db8:f53b::/48')
s6.lastAddress                        // '2001:db8:f53b:ffff:ffff:ffff:ffff:ffff'
s6.contains('2001:db8:f53a::1')       // false
s6.length                             // 2 ** 80 (approximate above 2 ** 53)
تنزيل الأداة