10 самых распространенных уязвимостей веб-безопасности

Опубликовано: 2022-03-11

Для слишком многих компаний передовой опыт веб-безопасности становится приоритетом только после того , как произошло нарушение безопасности. За годы работы специалистом по ИТ-безопасности я снова и снова видел, насколько неясным может быть мир вопросов безопасности веб-разработки для многих моих коллег-программистов.

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

В частности, это руководство фокусируется на 10 распространенных и серьезных ловушках веб-безопасности, о которых следует знать, включая рекомендации о том, как их можно смягчить. Основное внимание уделяется 10 основным веб-уязвимостям, выявленным Open Web Application Security Project (OWASP), международной некоммерческой организацией, целью которой является повышение безопасности программного обеспечения во всем мире.

Пример некоторых распространенных веб-уязвимостей, с которыми никто не хочет сталкиваться.

Перед тем, как мы начнем, небольшое руководство по кибербезопасности — аутентификация и авторизация

Общаясь с другими программистами и ИТ-специалистами, я часто сталкиваюсь с путаницей в отношении различия между авторизацией и аутентификацией. И, конечно же, тот факт, что аббревиатура auth часто используется для обоих, помогает усугубить эту распространенную путаницу. Эта путаница настолько распространена, что, возможно, эту проблему следует включить в этот пост как «Общая веб-уязвимость ноль».

Итак, прежде чем мы продолжим, давайте проясним различие между этими двумя терминами:

  • Аутентификация: проверка того, что человек является (или, по крайней мере, кажется) конкретным пользователем, поскольку он / она правильно предоставил свои учетные данные безопасности (пароль, ответы на контрольные вопросы, сканирование отпечатков пальцев и т. д.).
  • Авторизация: подтверждение того, что конкретный пользователь имеет доступ к определенному ресурсу или ему предоставлено разрешение на выполнение определенного действия.

Другими словами, аутентификация — это знание сущности, а авторизация — знание того, что может делать данная сущность. Имея это в виду, давайте рассмотрим 10 основных проблем безопасности в Интернете.

Распространенная ошибка веб-безопасности № 1: недостатки внедрения

Ошибки внедрения возникают из-за классической неспособности фильтровать ненадежные входные данные. Это может произойти, когда вы передаете нефильтрованные данные на SQL-сервер (SQL-инъекция), в браузер (XSS — мы поговорим об этом позже), на LDAP-сервер (LDAP-инъекция) или куда-либо еще. Проблема здесь в том, что злоумышленник может вводить команды в эти объекты, что приводит к потере данных и взлому браузеров клиентов.

Все, что ваше приложение получает из ненадежных источников, должно быть отфильтровано, желательно по белому списку. Вы почти никогда не должны использовать черный список, так как получить его правильно очень сложно и обычно легко обойти. Антивирусные программные продукты обычно предоставляют яркие примеры неудачных черных списков. Сопоставление с образцом не работает.

Предотвращение: хорошая новость заключается в том, что защита от инъекций — это «просто» вопрос правильной фильтрации ваших входных данных и размышлений о том, можно ли им доверять. Но плохая новость заключается в том, что все входные данные должны быть должным образом отфильтрованы, если только им нельзя безоговорочно доверять (но здесь на ум приходит поговорка «никогда не говори никогда»).

В системе с 1000 входов, например, успешной фильтрации 999 из них недостаточно, так как остается одно поле, которое может послужить ахиллесовым исцелением, чтобы вывести вашу систему из строя. И вы можете подумать, что поместить результат SQL-запроса в другой запрос — хорошая идея, поскольку база данных является доверенной, но если периметру нет, входные данные поступают косвенно от парней с недобросовестностью. Если вам интересно, это называется SQL-инъекцией второго порядка.

Поскольку фильтрацию довольно сложно сделать правильно (например, криптографию), я обычно советую полагаться на функции фильтрации вашего фреймворка: они доказали свою эффективность и тщательно проверены. Если вы не используете фреймворки, вам действительно нужно хорошенько подумать о том, действительно ли их использование имеет смысл в контексте безопасности вашего сервера. В 99% случаев это не так.

Распространенная ошибка веб-безопасности № 2: неверная аутентификация

Это набор нескольких проблем, которые могут возникнуть при нарушении аутентификации, но не все они связаны с одной и той же основной причиной.

Предполагая, что кто-то все еще хочет использовать свой собственный код аутентификации в 2014 году (о чем вы думаете??), я бы не советовал этого делать. Это чрезвычайно сложно сделать правильно, и существует множество возможных ловушек, и это лишь некоторые из них:

  1. URL-адрес может содержать идентификатор сеанса и передавать его кому-либо в заголовке реферера.
  2. Пароли могут быть не зашифрованы ни при хранении, ни при передаче.
  3. Идентификаторы сеанса могут быть предсказуемыми, поэтому получение доступа тривиально.
  4. Возможна фиксация сеанса.
  5. Возможен перехват сеанса, неправильно реализованные тайм-ауты или использование HTTP (без защиты SSL) и т. д.

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

Распространенная ошибка веб-безопасности № 3: Межсайтовый скриптинг (XSS)

Это довольно распространенная ошибка очистки ввода (по сути, частный случай распространенной ошибки № 1). Злоумышленник передает вашему веб-приложению теги JavaScript на входе. Когда этот ввод возвращается пользователю в несанированном виде, браузер пользователя выполнит его. Это может быть так же просто, как создать ссылку и убедить пользователя нажать на нее, или это может быть что-то гораздо более зловещее. При загрузке страницы скрипт запускается и, например, может быть использован для отправки ваших файлов cookie злоумышленнику.

Предотвращение. Существует простое решение для веб-безопасности: не возвращайте HTML-теги клиенту. Дополнительным преимуществом этого является защита от HTML-инъекций, аналогичной атаки, при которой злоумышленник внедряет обычный HTML-контент (например, изображения или громкие невидимые флеш-плееры) — не очень сильно, но, безусловно, раздражает («пожалуйста, остановите это!»). Обычно обходной путь заключается в простом преобразовании всех объектов HTML, чтобы <script> возвращался как &lt;script&gt; . Другим часто используемым методом очистки является использование регулярных выражений для удаления тегов HTML с использованием регулярных выражений для < и > , но это опасно, так как многие браузеры прекрасно интерпретируют сильно поврежденный HTML. Лучше преобразовать все символы в их экранированные аналоги.

Связанный: 9 основных вопросов по безопасности системы

Распространенная ошибка веб-безопасности № 4: небезопасные прямые ссылки на объекты

Это классический случай, когда вы доверяете пользовательскому вводу и платите за это уязвимостью системы безопасности. Прямая ссылка на объект означает, что внутренний объект, такой как файл или ключ базы данных, доступен пользователю. Проблема в том, что злоумышленник может предоставить эту ссылку, и, если авторизация либо не применяется (или нарушена), злоумышленник может получить доступ или сделать то, что ему следует запретить.

Например, в коде есть модуль download.php , который считывает и позволяет пользователю загружать файлы, используя параметр CGI для указания имени файла (например, download.php?file=something.txt ). То ли по ошибке, то ли по лени разработчик пропустил авторизацию из кода. Злоумышленник теперь может использовать это для загрузки любых системных файлов, к которым имеет доступ пользователь, работающий с PHP, например самого кода приложения или других данных, оставшихся на сервере, таких как резервные копии. О-о.

Другим распространенным примером уязвимости является функция сброса пароля, которая зависит от пользовательского ввода, чтобы определить, чей пароль мы сбрасываем. После нажатия действительного URL-адреса злоумышленник может просто изменить поле username в URL-адресе, чтобы сказать что-то вроде «admin».

Между прочим, оба этих примера я сам часто видел, появляясь «в дикой природе».

Предотвращение: правильно и последовательно выполняйте авторизацию пользователей и вносите варианты в белый список. Однако чаще всего всей проблемы можно избежать, сохраняя данные внутри и не полагаясь на то, что они передаются от клиента через параметры CGI. Переменные сеанса в большинстве фреймворков хорошо подходят для этой цели.

Распространенная ошибка веб-безопасности № 5: неправильная настройка безопасности

По моему опыту, веб-серверы и приложения, которые были неправильно настроены, встречаются гораздо чаще, чем те, которые были настроены правильно. Возможно, это потому, что нет недостатка в способах облажаться. Некоторые примеры:

  1. Запуск приложения с включенной отладкой в ​​рабочей среде.
  2. На сервере включен список каталогов, что приводит к утечке ценной информации.
  3. Запуск устаревшего программного обеспечения (например, плагины WordPress, старый PhpMyAdmin).
  4. Наличие ненужных служб, запущенных на машине.
  5. Не меняя ключи и пароли по умолчанию. (Случается гораздо чаще, чем вы думаете!)
  6. Предоставление злоумышленникам информации об обработке ошибок, например трассировки стека.

Предупреждение: иметь хороший (желательно автоматизированный) процесс «сборки и развертывания», который может запускать тесты при развертывании. Решение для неправильной настройки безопасности бедного человека — это перехватчики после фиксации, чтобы предотвратить выход кода с паролями по умолчанию и/или встроенными средствами разработки.

Распространенная ошибка веб-безопасности № 6: раскрытие конфиденциальных данных

Эта уязвимость веб-безопасности связана с криптографией и защитой ресурсов. Конфиденциальные данные должны быть зашифрованы всегда, в том числе при передаче и хранении. Без исключений. Информация о кредитной карте и пароли пользователей никогда не должны передаваться или храниться в незашифрованном виде, а пароли всегда должны быть хешированы. Очевидно, что алгоритм шифрования/хеширования не должен быть слабым — в случае сомнений стандарты веб-безопасности рекомендуют AES (256 бит и выше) и RSA (2048 бит и выше).

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

Профилактика:

  • При передаче: используйте HTTPS с надлежащим сертификатом и PFS (совершенная секретность пересылки). Не принимайте ничего через соединения, отличные от HTTPS. Имейте безопасный флаг на файлах cookie.

  • В хранилище: это сложнее. Прежде всего, вам нужно снизить воздействие. Если вам не нужны конфиденциальные данные, уничтожьте их. Данные, которых у вас нет, не могут быть украдены. Никогда не сохраняйте информацию о кредитной карте, так как вы, вероятно, не хотите иметь дело с совместимостью с PCI. Зарегистрируйтесь в платежной системе, такой как Stripe или Braintree. Во-вторых, если у вас есть конфиденциальные данные, которые вам действительно нужны, храните их в зашифрованном виде и убедитесь, что все пароли хешированы. Для хеширования рекомендуется использовать bcrypt. Если вы не используете bcrypt, изучите солевые и радужные таблицы.

И рискуя констатировать очевидное, не храните ключи шифрования рядом с защищаемыми данными . Это все равно, что хранить свой велосипед с замком, в котором есть ключ. Защитите свои резервные копии с помощью шифрования и держите ключи в секрете. И, конечно же, не теряйте ключи!

Распространенная ошибка веб-безопасности № 7: отсутствие контроля доступа на функциональном уровне

Это просто ошибка авторизации. Это означает, что при вызове функции на сервере не была выполнена правильная авторизация. Часто разработчики полагаются на тот факт, что пользовательский интерфейс был сгенерирован на стороне сервера, и думают, что функциональность, не предоставляемая сервером, не может быть доступна клиенту. Это не так просто, поскольку злоумышленник всегда может подделать запросы к «скрытым» функциям, и его не остановит тот факт, что пользовательский интерфейс не делает эти функции легко доступными. Представьте, что есть панель /admin , и кнопка присутствует в пользовательском интерфейсе только в том случае, если пользователь на самом деле является администратором. Ничто не мешает злоумышленнику обнаружить эту функциональность и злоупотребить ею, если авторизация отсутствует.

Предупреждение: На стороне сервера всегда должна выполняться авторизация. Да всегда. Никакие исключения или уязвимости не приведут к серьезным проблемам.

Распространенная ошибка веб-безопасности № 8: подделка межсайтовых запросов (CSRF)

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

В случае CSRF сторонний сайт отправляет запросы на целевой сайт (например, ваш банк) с помощью вашего браузера с вашими файлами cookie/сеансом. Например, если вы вошли в систему на одной вкладке на домашней странице вашего банка, и они уязвимы для этой атаки, другая вкладка может заставить ваш браузер неправильно использовать свои учетные данные от имени злоумышленника, что приведет к проблеме с запутанным заместителем. Заместитель — это браузер, который злоупотребляет своими полномочиями (сессионными куки-файлами), чтобы сделать то, что ему поручает злоумышленник.

Рассмотрим этот пример:

Злоумышленник Алиса хочет облегчить кошелек Тодда, переведя ей часть его денег. Банк Тодда уязвим для CSRF. Чтобы отправить деньги, Тодд должен получить доступ к следующему URL-адресу:

http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243

После того, как этот URL-адрес будет открыт, Тодду будет представлена ​​страница успеха, и передача будет выполнена. Алиса также знает, что Тодд часто посещает подконтрольный ей сайт blog.aliceisawesome.com, где она размещает следующий фрагмент:

<img src=http://example.com/app/transferFunds?amount=1500&destinationAccount=4673243243 width=0 height=0 />

При посещении веб-сайта Алисы браузер Тодда считает, что Алиса ссылается на изображение, и автоматически отправляет HTTP-запрос GET для получения изображения, но на самом деле это дает указание банку Тодда перевести Алисе 1500 долларов.

Между прочим, помимо демонстрации CSRF-уязвимости, этот пример также демонстрирует изменение состояния сервера с помощью идемпотентного HTTP-запроса GET, что само по себе является серьезной уязвимостью. Запросы HTTP GET должны быть идемпотентными (безопасными), что означает, что они не могут изменить ресурс, к которому осуществляется доступ. Никогда, никогда не используйте идемпотентные методы для изменения состояния сервера.

Забавный факт: CSRF также является методом, который люди использовали для заполнения файлов cookie в прошлом, пока аффилиаты не поумнели.

Предотвращение: храните секретный токен в скрытом поле формы, которое недоступно со стороннего сайта. Вы, конечно, всегда должны проверять это скрытое поле. Некоторые сайты также запрашивают ваш пароль при изменении конфиденциальных настроек (например, электронной почты с напоминанием о пароле), хотя я подозреваю, что это делается для предотвращения неправомерного использования ваших заброшенных сеансов (например, в интернет-кафе).

Распространенная ошибка веб-безопасности № 9: использование компонентов с известными уязвимостями

Название говорит само за себя. Я бы снова классифицировал это как проблему обслуживания/развертывания. Прежде чем внедрять новый код, проведите небольшое исследование, возможно, аудит. Использование кода, полученного от случайного человека на GitHub или каком-либо форуме, может быть очень удобным, но не лишено риска серьезной уязвимости веб-безопасности.

Я видел много случаев, например, когда сайты переходили во владение (т. е. когда посторонний человек получал административный доступ к системе) не потому, что программисты были глупы, а потому, что стороннее программное обеспечение оставалось неисправленным в течение многих лет в производстве. Например, это постоянно происходит с плагинами WordPress. Если вы думаете, что они не найдут вашу скрытую установку phpmyadmin , позвольте мне познакомить вас с dirbuster.

Урок здесь заключается в том, что разработка программного обеспечения не заканчивается с развертыванием приложения. Должна быть документация, тесты и планы того, как поддерживать и обновлять его, особенно если он содержит сторонние компоненты или компоненты с открытым исходным кодом.

Профилактика:

  • Соблюдайте осторожность. Помимо очевидной осторожности при использовании таких компонентов, не будьте копипаст-кодером. Внимательно проверьте фрагмент кода, который вы собираетесь поместить в свое программное обеспечение, так как он может быть поврежден без возможности восстановления (или, в некоторых случаях, преднамеренно вредоносным — таким образом иногда невольно провоцируются атаки на веб-безопасность).

  • Будьте в курсе. Убедитесь, что вы используете последние версии всего, чему вы доверяете, и регулярно обновляйте их. По крайней мере, подпишитесь на рассылку новостей о новых уязвимостях безопасности, касающихся продукта.

Распространенная ошибка веб-безопасности № 10: непроверенные перенаправления и перенаправления

Это еще раз проблема фильтрации ввода. Предположим, что на целевом сайте есть модуль redirect.php , который принимает URL-адрес в качестве параметра GET . Манипулирование параметром может создать URL-адрес targetsite.com , который перенаправляет браузер на malwareinstall.com . Когда пользователь увидит ссылку, он увидит targetsite.com/blahblahblah , который, по мнению пользователя, является надежным и безопасным для нажатия. Мало ли они знают, что это фактически перенесет их на страницу с вредоносным ПО (или любую другую вредоносную). Кроме того, злоумышленник может перенаправить браузер на targetsite.com/deleteprofile?confirm=1 .

Стоит упомянуть, что вставка недезинфицированного пользовательского ввода в HTTP-заголовок может привести к внедрению заголовка, что довольно плохо.

Профилактика: Варианты включают:

  • Не делайте редиректы вообще (они редко нужны).
  • Имейте статический список допустимых местоположений для перенаправления.
  • Внесите в белый список определяемый пользователем параметр, но это может быть сложно.

Эпилог

Я надеюсь, что мне удалось немного пощекотать ваш мозг этим постом и внести здоровую дозу паранойи и осведомленности об уязвимостях безопасности веб-сайтов.

Основной вывод здесь заключается в том, что вековые практики программного обеспечения существуют по какой-то причине, и то, что применялось в прошлом для переполнения буфера, по-прежнему применимо к маринованным строкам в Python сегодня. Протоколы безопасности помогают писать (более) правильные программы, к чему должны стремиться все программисты.

Пожалуйста, используйте эти знания ответственно и не тестируйте страницы без разрешения!

Для получения дополнительной информации и более конкретных атак на стороне сервера посетите страницу: https://www.owasp.org/index.php/Category:Attack.

Мы приветствуем отзывы об этом посте и рекомендации по смягчению последствий. Планируются будущие публикации по теме, в частности по вопросу о распределенном отказе в обслуживании (DDoS) и устаревших (не веб) уязвимостях ИТ-безопасности. Если у вас есть конкретный запрос о том, о какой веб-защите написать, пожалуйста, не стесняйтесь обращаться ко мне напрямую по адресу [email protected].

За безопасность сайта! Ваше здоровье.

Связанный:
  • Учебник по JSON Web Token: пример в Laravel и AngularJS
  • Производительность и эффективность: работа с HTTP/3