Лекция
Привет, Вы узнаете о том , что такое уязвимость api, Разберем основные их виды и особенности использования. Еще будет много подробных примеров и описаний. Для того чтобы лучше понимать что такое уязвимость api, уязвимость jwt , настоятельно рекомендую прочитать все из категории Криптография и Криптоанализ. Стеганография. Защита Информации и информационная безопасность. .
API-интерфейсы бывают разных форм и размеров, методы атаки на API будут сильно различаться в зависимости от этих форм и размеров. Было бы невозможно описать все типы атак в одном блоге, но мы рассмотрим их сразу несколько!
Как и веб-приложения, API-интерфейсы могут иметь разные уровни видимости. Некоторые из них могут быть доступны в Интернете, а другие доступны только для внутреннего пользования. Один из наиболее элементарных способов взлома API - это просто получение доступа к API, который должен быть для вас недоступен. Это может быть достигнуто с помощью различных методов, в том числе:
Существует множество передовых методов, которые могут помочь предотвратить непреднамеренное раскрытие API, включая реализацию строгих методов развертывания, принудительный принцип наименьших привилегий через IAM и сегментацию сети.
Для API, требующих аутентификации, возвращаемые данные часто являются динамическими и привязаны к каждому ключу API. Например, доступ /api/v1/user
от имени Мистика должен возвращать сведения о Мистике , а доступ к той же конечной точке, что и Ителла, должен возвращать сведения о Инелла.
Распространенная неправильная конфигурация возникает, когда API не использует стандартный Authorization
заголовок, а использует настраиваемый заголовок, например Some-API-Key
. Кэширующие серверы могут не распознать это как аутентифицированный запрос и могут кэшировать его.
Если это так и заголовки Cache-Control
или отсутствуют Pragma
, простой доступ /api/v1/user
может раскрыть информацию другого пользователя.
Исправление для этого - реализовать Cache-Control
или Pragma
заголовки и использовать стандартный Authorization
заголовок.
Мы не должны сбрасывать со счетов самый элементарный способ аутентификации. Обнаружение ключа API любым способом может предоставить вам доступ к API. Что еще хуже, API-интерфейсы, предназначенные для внутреннего использования, часто не нуждаются в реализации сложных потоков аутентификации и, таким образом, могут реализовывать статический токен в качестве своей аутентификации. Секретные токены могут быть обнаружены в репозиториях кода, клиентском JavaScript, перехватывающем трафике и т. Д.
Внедрение сканирования кода в конвейер DevOps часто приводит к обнаружению ключей API до того, как они будут развернуты там, где их не должно быть. Некоторые поставщики репозиториев кода (включая GitHub ) также имеют возможность обнаруживать ключи API до того, как они будут отправлены.
Если ваш токен API представляет собой три больших двоичных объекта base64, разделенных двумя точками (.), Вероятно, это веб- токен JSON (JWT) . Как и многие другие вещи, эти токены теоретически безопасны, но есть много способов испортить реализацию, что приведет к проблемам с безопасностью. Прежде чем мы углубимся в атаки JWT, мы рассмотрим очень краткое руководство по JWT.
Вот пример токена JWT, раскрашенный для вашего эстетического восприятия:
Есть три строки в кодировке base64, разделенные точками, первая секция (окрашенная в красный цвет) - это header
. Второй (окрашенный в фиолетовый цвет) - это payload
, а третий (окрашенный в синий цвет) - это signature
.
Если мы декодируем первый раздел, также известный как заголовок, мы увидим следующее:
{
"alg": "HS256",
"typ": "JWT"
}
Здесь описывается алгоритм, который мы используем (HS256), и тип токена (JWT). Если вы еще не работали с JWT, вы могли подумать: «Зачем нам нужен алгоритм?» . Мы скоро туда доберемся!
Если мы декодируем вторую секцию, также известную как полезная нагрузка, мы увидим следующее:
{
"sub": "1234567890",
"name": "Intella Icu",
"iat": 1616161616
}
Этот раздел может содержать что угодно, но, как минимум, он должен содержать какой-то идентификатор пользователя и тайм-аут (iat).
Третий раздел (также известный как подпись) подписывает первые два раздела секретным ключом. В этом случае он подписывается с помощью алгоритма HS256, который можно определить, посмотрев на значение «alg» в заголовке. По идее, секретный ключ должен быть известен только владельцу приложения. Когда приложение получает токен JWT, оно может проверить его законность, расшифровав подпись и сравнив ее с данными в заголовке и полезной нагрузке. Если данные совпадают, данные проверяются, в противном случае они недействительны.
Так зачем кому-то использовать JWT? Это потому, что это исключает необходимость управления сеансом на стороне сервера. Обычно, когда пользователь входит в систему, приложение назначает ему секретный токен и сохраняет этот же токен в базе данных. Каждый раз, когда пользователь делает запрос со своим токеном, приложение должно проверить, находится ли токен в базе данных. Если это так, пользователю разрешено продолжить, в противном случае - нет. Когда мы используем JWT, мы вводим метод доверия к данным, отправляемым от клиента, вместо того, чтобы полностью доверять информации, хранящейся в базе данных. Если приложение получает токен JWT, который можно проверить с помощью секретного ключа, у приложения нет причин не доверять ему.
Как мы уже говорили ранее, теоретически токены JWT полностью безопасны. Проблема в том, что они часто реализуются небезопасно. Вот некоторые примеры:
iat
Лучшим средством устранения недостатков JWT является использование широко используемой, авторитетной библиотеки JWT для всех операций JWT.
Авторизация - это процесс проверки, имеет ли аутентифицированный пользователь доступ к определенному пользователю. Распространенная уязвимость, связанная с авторизацией, известна как незащищенная прямая ссылка на объект (IDOR). Об этом говорит сайт https://intellect.icu . Например, в API для приложения для выставления счетов у нас может быть конечная точка, которая используется для получения деталей счета:
/api/v1/invoice/?id=12
id
Параметр является идентификатором счета , который должен быть возвращен. Если эта конечная точка защищена, я смогу получать сведения только о принадлежащих мне счетах. Например, если я создал счет с идентификатором 12, он должен вернуть данные. Если я попытаюсь получить доступ к счету, который я не создавал, просматривая его /api/v1/invoice/?id=13
, он должен вернуть ошибку.
Если я могу изменить идентификатор для просмотра сведений о счетах других пользователей, это уязвимость, известная как IDOR.
Чтобы противостоять проблемам IDOR, многие API сегодня используют UUID в качестве идентификаторов объектов. UUID выглядит так:
f1af4910-e77f-22eb-beb2-0242ac131112
Важно отметить, что использование UUID в качестве идентификаторов не является допустимым методом устранения проблем IDOR. Фактически, UUID RFC специально называет это:
Не думайте, что UUID трудно угадать; они не должны использоваться, например, в качестве средств защиты (идентификаторы, простое владение которыми предоставляет доступ). Предсказуемый источник случайных чисел усугубит ситуацию.
Хотя рекомендуется использовать UUID в качестве идентификаторов объектов вместо целых чисел, они никогда не должны использоваться в качестве единственной защиты от атак IDOR.
Проблемы с авторизацией обычно трудно обнаружить автоматическим способом. Структура кодовой базы должна быть настроена таким образом, чтобы было сложно допустить ошибки авторизации на определенных конечных точках. Чтобы достичь этого, меры авторизации должны быть реализованы как можно выше в стеке. Возможно на уровне класса или с использованием промежуточного программного обеспечения.
Часто встречаются ситуации, когда API, на который вы атакуете, не имеет документации (или, по крайней мере, ее нет для вас). Также довольно часто API с документацией будет иметь конечные точки, выходящие за рамки документированного. Иногда само существование этих конечных точек может быть проблемой безопасности - например, конечная точка может быть предназначена для административных целей и позволяет вам выполнять административные задачи в качестве пользователя с ограниченными правами. В других случаях эти конечные точки могут представлять уязвимости просто потому, что они не были протестированы так тщательно, как те, которые легко обнаружить.
Вот несколько методов, которые мы можем использовать для обнаружения недокументированных конечных точек:
/api/v1/somestring
в адрес может привести к ошибке, в которой говорится что-то вроде Invalid route, valid routes are [/users,/invoices,/orders]
.Наличие надежного структурированного метода и процесса для документирования функциональности API может избавить от многих головных болей в будущем. Swagger (OpenApi)- отличный стандарт именно для этого. Кроме того, лучше всего спланировать функциональность API с помощью документации, прежде чем писать код, а не наоборот.
Когда организация выпускает API, она может взаимодействовать с множеством различных приложений. Если API обновляется в любой момент, это может привести к критическим изменениям для одного или нескольких из этих приложений. По этой причине несколько версий API часто реализуются как средство поддержки старых схем API, а также для обновления API со временем для новых пользователей.
Стоит протестировать все версии API. В более старых версиях все еще могут быть проблемы с безопасностью, которые с тех пор были исправлены в новой версии, а в более новых / новейших / бета-версиях могут возникать новые проблемы с безопасностью.
Распространенная схема управления версиями API:
/api/v1/
/api/v2/
/api/v3/
/api/alfa/
Всегда стоит проверять имена непроизводственных маршрутов, такие как:
Версии API могут поддерживаться с определенным жизненным циклом. Например, когда вы выпускаете версию 2 API, вы можете уведомить своих пользователей, что версия 1 достигнет конца срока службы (EoL) и будет прекращена в определенный день в будущем. Предварительные / бета-версии должны быть общедоступными только в том случае, если они были тщательно протестированы на наличие проблем безопасности.
В большинстве случаев API-интерфейсы не имеют защиты от количества запросов, которые пользователь может запросить. Это называется «отсутствие ограничения скорости» и возникает, когда злоумышленник может вызвать API тысячи раз, чтобы вызвать какое-то непреднамеренное поведение. Сервер будет пытаться выполнить каждый из этих запросов, и это потенциально может:
Давайте рассмотрим сценарий атаки, в котором нет ограничения скорости для конечной точки API, которая проверяет учетные данные:
GET/POST /api/v1/auth?login=intellect.icu&password=mypassword
Обычно вы не увидите пароль, отправленный в таком запросе GET, но для целей этой демонстрации допустим, что вы видите. Чтобы подобрать пароль в указанной выше конечной точке, злоумышленник может использовать специальные инструменты . Они позволяют настраивать различные виды атак грубой силы, но для этого примера мы будем кормить его простым списком паролей.
В течение нескольких секунд Intruder выполнит сотни запросов API, пытаясь использовать другой пароль для каждого запроса.
GET/POST /api/v1/auth?login=intellect.icu&password=somepassword1 GET/POST /api/v1/auth?login=intellect.icu&password=somepassword2 GET/POST /api/v1/auth?login=intellect.icu&password=somepassword3 GET/POST /api/v1/auth?login=intellect.icu&password=somepassword4
. . .
GET/POST /api/v1/auth?login=intellect.icu&password=true password
Поскольку ограничения по скорости нет, сервер с радостью предоставит ответы на все эти запросы, и злоумышленник может продолжать подбирать разные пароли как можно быстрее, пока не будет найден правильный.
Для защиты от ошибок, ограничивающих скорость, приложение должно установить ограничение на то, как часто пользователь может запрашивать API в течение определенного периода времени. Установленный точный предел будет зависеть от варианта использования этого API или конечной точки.
Ограничение скорости может быть реализовано разными способами. Для каждой учетной записи, для каждого IP-адреса, для каждой конечной точки, для всего API и т. Д. Некоторые обратные прокси-серверы также могут использоваться для реализации регулирования в масштабе всего приложения без дополнительной разработки. Точная реализация, которую вы будете использовать, будет зависеть от требований вашего конкретного приложения.
Состояние гонки - это когда два или более запроса отправляются в API за одну и ту же миллисекунду. Если у API нет механизма для обработки этого сценария, это может привести к тому, что API обработает запросы непреднамеренным образом.
Потенциальный сценарий атаки из-за состояния гонки может возникнуть при использовании скидок или промокодов в уязвимом приложении электронной коммерции.
POST /api/v1/discount { "code" , "cupon" , "amount" : "15" }
После настройки атаки в Turbo Intruder злоумышленник может отправить несколько одновременных запросов к API для погашения этого промокода.
Если API не аннулирует промокод сразу после получения первого параллельного запроса, размер скидки может быть удвоен, утроен и т. Д.
Эта атака называется «Состояние гонки», потому что это гонка между тем, как быстро злоумышленник отправляет запросы на изменение ресурса, и тем, как быстро приложение обновляет этот конкретный ресурс.
К сожалению, устранение проблем, связанных с состоянием гонки, часто означает снижение производительности. Методы смягчения условий гонки включают использование блокировок и других поточно-ориентированных функций. Большинство языков программирования имеют встроенную поточно-ориентированную функциональность, но обычно ее нужно указывать вручную.
XXE означает внешнюю сущность XML, и эту уязвимость внедрения можно проверить везде, где API используется для обработки данных XML. API-интерфейсы SOAP также могут быть уязвимы для внедрения XXE, поскольку они основаны на XML.
Конечная точка API, использующая XML, выглядит примерно так:
XML-документ использует сущности для представления одного объекта данных, а определение типа XML-документа (DTD) используется для определения сущностей, которые будут использоваться, структуры документа и т. Д.
Внедрение XXE относится к случаям, когда злоумышленник вводит настраиваемые внешние сущности, которые находятся за пределами указанного DTD. После того, как эти внешние объекты проанализированы API, он может позволить злоумышленнику получить доступ к внутренним файлам приложения, перейти на SSRF, передать конфиденциальные данные в домен, контролируемый злоумышленником, или DOS-сервер.
Это пример запроса, в котором злоумышленник внедрил внешнюю настраиваемую сущность с именем xxe, и цель этой сущности - получить внутренний файл:
Если API позволяет использовать стандартный анализатор XML для обработки данных, то этот внедренный внешний объект будет обработан приложением и вернет содержимое /etc/passwd
злоумышленнику.
Убедитесь, что используемый синтаксический анализатор XML настроен так, чтобы не анализировать объекты XML.
Несмотря на то, что API может использовать JSON в качестве формата данных для связи, базовый сервер / инфраструктура может по-прежнему принимать другие форматы данных, такие как XML. Поэтому, когда вы видите API с content-Type
из application/json
, вы все равно можете попробовать протестировать XXE, переключив его значение наContent-Type: text/xml
Например, если API использует JSON:
POST /api/v1/user HTTP/1.1 Host : intellect.icu Content-type : application / json
Его можно изменить для отправки данных XML следующим образом:
Эта ошибка действительно существует только в фреймворках, которые предназначены для приема нескольких форматов, где каждый формат соответствует типу объекта. В этих случаях у фреймворков обычно есть возможность занести доступные форматы в белый список. Следует отметить, что в 2021 году это довольно редко.
API-интерфейсы обычно поддерживают различные типы HTTP-методов. Некоторые из них являются общими GET
, POST
, PATCH
, DELETE
и OPTIONS
.Если запрос GET отправляется в точке , где приложение ожидает запрос POST, то это может привести к применению отвечающей самым неожиданным образом.
Возьмем для примера CSRF. CSRF (подделка межсайтовых запросов) - это когда злоумышленник обманом заставляет жертву отправить запрос, который может вызвать действия по изменению состояния в учетной записи жертвы. Эти изменения могут быть любыми, от изменения личных данных жертвы и, в некоторых случаях, даже изменения пароля жертвы, ведущего к полному захвату учетной записи.
Обычный запрос на изменение личных данных жертвы может выглядеть примерно так:
Изучив приведенный выше запрос, мы можем сделать вывод, что CSRF-атака невозможна, поскольку csrftoken
значение отправляется в теле запроса. Однако, если API не ограничивает методы HTTP, которые могут использоваться для этого запроса, злоумышленник может обойти эту защиту, отправив этот запрос с помощью метода GET.
GET /api/v1/user?name=some&email = some@example.com&location=mars host : intellect.icu
Кроме того, иногда сервер просто не проверяет токен CSRF или принимает запрос, если в запросе вообще отсутствует параметр токена CSRF.
Другая распространенная уязвимость в REST API - это когда разрешения были правильно применены к конечной точке, но только для одного HTTP-глагола. Например, вы не сможете ПОЛУЧИТЬ записи других людей, но сможете редактировать их записи, используя команду PATCH.
Укажите в маршрутах HTTP-команды вручную. Не используйте глаголы без надобности и убедитесь, что все указанные конечные точки имеют одинаковые элементы управления, применяемые ко всем глаголам. Некоторые фреймворки делают это автоматически, другие - нет.
Недостатки серверной инъекции, такие как SQL-инъекция, RCE, внедрение команд и SSRF, могут существовать в API так же, как они существуют в обычных веб-приложениях. Всякий раз, когда какие-либо внедренные данные напрямую передаются интерпретатору на бэкэнде, это оставляет злоумышленнику место для отправки целевых запросов и команд для доступа к внутренним данным или выполнения произвольного кода.
Например, давайте протестируем SSRF по следующему запросу API:
POST /api/v1/user host : intellect.icu
{"avatar" : "https://www.example.com/me.jpg" } Злоумышленник может попытаться использовать SSRF на websiteполе, отправив такой запрос:
POST /api/v1/user host : intellect.icu
{ "avatar" : "https://localhost/admin " }
Если внутренний интерпретатор не проверяет avatar
значение должным образом, это может привести к тому, что злоумышленник использует SSRF и успешно получит доступ к внутренним данным.
Точно так же злоумышленник также может попытаться выполнить SQL-инъекцию, если данные в этом запросе неправильно проверены:
POST /api/v1/orders
host : intellect.icu
{ "offset" : 0 , "limit" : 10 , "scope" : "all" , }
Посмотрев на тело запроса, мы можем получить подсказку, что значения этих параметров отправляются интерпретатору внутренней базы данных. Следовательно, мы можем попытаться выполнить SQL-инъекцию, изменив эти значения на целевые запросы:
POST /api/v1/orders
host : intellect.icu
{ "offset" : 0 , "limit" : 10 , "scope" : "SELECT sleep (100)" , } Еще раз, если интерпретатор не проверяет эти значения должным образом, это может привести к SQL-инъекции, когда злоумышленник может вызвать задержку по времени в базе данных и даже похитить конфиденциальные данные.
Устранение уязвимостей инъекций в API-интерфейсах по сути то же самое, что устранение уязвимостей инъекций в веб-приложениях. Сканеры SAST / DAST могут помочь в этом, но методы безопасной разработки - лучшее решение. Параметризуйте запросы SQL, по возможности используйте ORM и авторитетные библиотеки, не доверяйте вводу пользователя никогда!
Исследование, описанное в статье про уязвимость api, подчеркивает ее значимость в современном мире. Надеюсь, что теперь ты понял что такое уязвимость api, уязвимость jwt и для чего все это нужно, а если не понял, или есть замечания, то не стесняйся, пиши или спрашивай в комментариях, с удовольствием отвечу. Для того чтобы глубже понять настоятельно рекомендую изучить всю информацию из категории Криптография и Криптоанализ. Стеганография. Защита Информации и информационная безопасность.
Комментарии
Оставить комментарий
информационная безопасность - Криптография и Криптоанализ. Стеганография. Защита Информации
Термины: информационная безопасность - Криптография и Криптоанализ. Стеганография. Защита Информации