Назад к обновлениям
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

Категории