العودة إلى التحديثات
New releaseSep 13, 2026

sj v2.8.2

أداة لتدقيق نقاط النهاية المُعرفة في ملفات تعريف (Swagger/OpenAPI) المكشوفة.

مشاركة

sj (Swagger Jacker)

sj هي أداة سطر أوامر مصممة للمساعدة في تدقيق ملفات تعريف Swagger/OpenAPI المكشوفة من خلال فحص نقاط نهاية API المرتبطة بها بحثًا عن مصادقة ضعيفة. كما توفر قوالب أوامر لاختبار الثغرات يدويًا.

تقوم بذلك عن طريق تحليل ملف التعريف بحثًا عن المسارات والمعاملات والطرق المقبولة قبل استخدام النتائج مع أحد الأوامر الفرعية الخمسة:

  • automate - يصيغ سلسلة من الطلبات ويحلل رمز الحالة للاستجابة.
  • prepare - ينشئ قائمة بالأوامر لاستخدامها في الاختبار اليدوي.
  • endpoints - ينشئ قائمة بمسارات API الخام. لن يتم استبدال قيم المسار ببيانات الاختبار.
  • brute - يرسل سلسلة من الطلبات إلى هدف للعثور على تعريفات العمليات بناءً على مسارات الملفات الشائعة الاستخدام.
  • convert - يحول ملف التعريف من الإصدار v2 إلى v3.

البناء

للترجمة من المصدر، تأكد من تثبيت إصدار Go >= 1.22.5 وقم بتشغيل go build من داخل المستودع:

$ git clone https://github.com/BishopFox/sj.git
$ cd sj/
$ go build .

التثبيت

لتثبيت أحدث إصدار من الأداة، قم بتشغيل:

$ go install github.com/BishopFox/sj@latest

# Note: you may also need to place the path to your Go binaries within your PATH environment variable:
$ export PATH=$PATH:~/go/bin

الاستخدام

استخدم الأمر automate لإرسال سلسلة من الطلبات إلى كل نقطة نهاية محددة وتحليل رمز الحالة لكل استجابة.

$ sj automate -u https://petstore.swagger.io/v2/swagger.json -qi -p http://127.0.0.1:8080               

Gathering API details.
⚠  POST     500  /v2/pet
⚠  PUT      500  /v2/pet
✓  GET      200  /v2/pet/findByStatus
✓  GET      200  /v2/pet/findByTags
✓  GET      200  /v2/pet/1
✓  POST     200  /v2/pet/1
⚠  POST     N/A  /v2/pet/1/uploadImage
✓  GET      200  /v2/store/inventory
⚠  POST     N/A  /v2/store/order
⚠  GET      N/A  /v2/store/order/1
✓  POST     200  /v2/user
⚠  POST     N/A  /v2/user/createWithArray
⚠  POST     N/A  /v2/user/createWithList
✓  GET      200  /v2/user/login
✓  GET      200  /v2/user/logout
✓  GET      200  /v2/user/bishopfox
✓  PUT      200  /v2/user/bishopfox

يمكنك استخدام العلامة --replay-proxy لإعادة تشغيل الطلبات المطابقة عبر وكيل منفصل (مثل Burp Suite). يتيح لك ذلك توجيه جميع حركة المرور عبر وكيل واحد (أو مباشرة) مع إرسال النتائج المثيرة للاهتمام فقط إلى وكيل الاعتراض الخاص بك:

$ sj automate -u https://petstore.swagger.io/v2/swagger.json -qi --replay-proxy http://127.0.0.1:8080

يمكنك أيضًا دمجه مع --proxy لتوجيه حركة مرور الفحص عبر وكيل مختلف أثناء إعادة تشغيل المطابقات إلى Burp:

$ sj automate -u https://petstore.swagger.io/v2/swagger.json -qi -p http://proxy:9090 --replay-proxy http://127.0.0.1:8080

يمكنك أيضًا طلب إخراج مطوّل لرؤية الاستجابة الجزئية (أو الكاملة):

$ sj automate -u https://petstore.swagger.io/v2/swagger.json -qi -p http://127.0.0.1:8080 -v           

Gathering API details.
⚠  POST     500  /v2/pet
   {"code":500,"type":"unknown","message":"something 
⚠  PUT      500  /v2/pet
   {"code":500,"type":"unknown","message":"something 
✓  GET      200  /v2/pet/findByStatus
   []
✓  GET      200  /v2/pet/findByTags
   []
✓  GET      200  /v2/pet/1
   {"id":1,"category":{"id":1,"name":"cat"},"name":"d
✓  POST     200  /v2/pet/1
   {"code":200,"type":"unknown","message":"1"}
⚠  POST     N/A  /v2/pet/1/uploadImage
✓  GET      200  /v2/store/inventory
   {"sold":115,"bishopfox":1,"SOLD":1,"string":224,"d
⚠  POST     N/A  /v2/store/order
⚠  GET      N/A  /v2/store/order/1
✓  POST     200  /v2/user
   {"code":200,"type":"unknown","message":"1"}
⚠  POST     N/A  /v2/user/createWithArray
⚠  POST     N/A  /v2/user/createWithList
✓  GET      200  /v2/user/login
   {"code":200,"type":"unknown","message":"logged in 
✓  GET      200  /v2/user/logout
   {"code":200,"type":"unknown","message":"ok"}
✓  GET      200  /v2/user/bishopfox
   {"id":1,"username":"bishopfox","firstName":"bishop
✓  PUT      200  /v2/user/bishopfox
   {"code":200,"type":"unknown","message":"1"}

استخدم الأمر prepare لإعداد قائمة بالأوامر للاختبار اليدوي. يدعم حاليًا كلاً من curl و sqlmap. من المحتمل أن تحتاج إلى تعديلها قليلاً.

$ sj prepare -u https://petstore.swagger.io/v2/swagger.json -qi -p http://127.0.0.1:8080

$ curl -X POST "https://petstore.swagger.io/v2/pet" -H 'Content-Type: application/json' -d '{"category":{"id":1,"name":"bishopfox"},"id":1,"name":"doggie","photoUrls":"https://bishopfox.com","status":"available","tags":[{"id":1,"name":"bishopfox"}]}'
$ curl -X PUT "https://petstore.swagger.io/v2/pet" -H 'Content-Type: application/json' -d '{"category":{"id":1,"name":"bishopfox"},"id":1,"name":"doggie","photoUrls":"https://bishopfox.com","status":"available","tags":[{"id":1,"name":"bishopfox"}]}'
$ curl -X GET "https://petstore.swagger.io/v2/pet/findByStatus?status=1"
$ curl -X GET "https://petstore.swagger.io/v2/pet/findByTags?tags=1"
$ curl -X GET "https://petstore.swagger.io/v2/pet/1"
$ curl -X POST "https://petstore.swagger.io/v2/pet/1" -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=bishopfox&status=bishopfox'
$ curl -X POST "https://petstore.swagger.io/v2/pet/1/uploadImage" -H 'Content-Type: application/x-www-form-urlencoded' -d 'additionalMetadata=bishopfox&file=1'
$ curl -X GET "https://petstore.swagger.io/v2/store/inventory"
$ curl -X POST "https://petstore.swagger.io/v2/store/order" -H 'Content-Type: application/json' -d '{"complete":true,"id":1,"petId":1,"quantity":1,"shipDate":"1990-01-01","status":"placed"}'
$ curl -X GET "https://petstore.swagger.io/v2/store/order/1"
$ curl -X POST "https://petstore.swagger.io/v2/user" -H 'Content-Type: application/json' -d '{"email":"[email protected]","firstName":"bishopfox","id":1,"lastName":"bishopfox","password":"bishopfox","phone":"bishopfox","userStatus":1,"username":"bishopfox"}'
$ curl -X POST "https://petstore.swagger.io/v2/user/createWithArray" -H 'Content-Type: application/json' -d '[{"email":"[email protected]","firstName":"bishopfox","id":1,"lastName":"bishopfox","password":"bishopfox","phone":"bishopfox","userStatus":1,"username":"bishopfox"}]'
$ curl -X POST "https://petstore.swagger.io/v2/user/createWithList" -H 'Content-Type: application/json' -d '[{"email":"[email protected]","firstName":"bishopfox","id":1,"lastName":"bishopfox","password":"bishopfox","phone":"bishopfox","userStatus":1,"username":"bishopfox"}]'
$ curl -X GET "https://petstore.swagger.io/v2/user/login?username=bishopfox&password=bishopfox"
$ curl -X GET "https://petstore.swagger.io/v2/user/logout"
$ curl -X GET "https://petstore.swagger.io/v2/user/bishopfox"
$ curl -X PUT "https://petstore.swagger.io/v2/user/bishopfox" -H 'Content-Type: application/json' -d '{"email":"[email protected]","firstName":"bishopfox","id":1,"lastName":"bishopfox","password":"bishopfox","phone":"bishopfox","userStatus":1,"username":"bishopfox"}'

أنواع محتوى جسم الطلب المتعددة

غالبًا ما تعلن العملية عن نفس الجسم تحت عدة أنواع محتوى. بشكل افتراضي، يرسل sj النوع الأكثر احتمالاً للقبول، مع تفضيل application/json، ثم application/x-www-form-urlencoded، ثم multipart/form-data، ثم XML. الاختيار حتمي، لذا تنتج التشغيلات المتكررة أوامر متطابقة.

نظرًا لأن محلل JSON ومحلل XML يمثلان سطح هجوم مختلف، فإن --all-content-types يرسل كل نوع معلن بدلاً من النوع المفضل فقط:

$ sj prepare -l spec.yaml -T https://api.example.com -q --all-content-types

$ curl -X POST "https://api.example.com/multi" -H 'Content-Type: application/json' -d '{"name":"bishopfox","size":1}'
$ curl -X POST "https://api.example.com/multi" -H 'Content-Type: application/x-www-form-urlencoded' -d 'name=bishopfox&size=1'
$ curl -X POST "https://api.example.com/multi" -F 'name=bishopfox' -F 'size=1'
$ curl -X POST "https://api.example.com/multi" -H 'Content-Type: application/xml' -d '<name>bishopfox</name><size>1</size>'

لاحظ أن هذا يضاعف عدد الطلبات المرسلة إلى الهدف، وأن --replay-proxy يستقبل كل واحد منها.

الفئات