Спидран по 13 уязвимостям на сайтах. Основные понятия, и средства защиты

в 7:02, , рубрики: php, безопасность, взлом сайтов, информационная безопасность, серверы

Недавно по работе собирал своего рода лекцию по веб-безопасности, ознакомился с известным рейтингом уявзимостей OWASP 2013 года, но с удивлением обнаружил, что корректной инфы на русском языке крайне мало, или её практически нет.

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

Некоторые из предоставленных в списке уязвимостей уже расписаны и не раз — известный факт, но без них список был бы неполным. Поэтому сразу дам небольшое содержание поста:

1. SQL Injection

Материала на сайте предостаточно, мне лично понравилась эта статья.

2. Некорректная аутентификация и управление сессией

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

index.php?PHPSESSID=jf843jgk4ogkfdjfgomg84o4og54mg

Как видите, ID передаётся в открытом виде, в то время как с куками он скрыт в заголовке HTTP-запроса.
Для этого предусмотрели настройку запрета на передачу сессии через URL:

php.ini
session.use_trans_sid=0;
session.use_only_cookies=1;

.htaccess
php_flag session.use_trans_sid Off
php_flag session.use_only_cookies On

Использование шифрования

Если на вашем сайта должна храниться/передаваться конфиденциальная информация (деньги, номера кошельков, состояние здоровья), то стоит использовать зашифрованные протоколы с сертификатом SSL.
При этом стоит при установке cookie выставлять шестой параметр secure = 1.

setcookie ('example', 'content', 0, '', '', 1);

Если вы храните пароль в переменной $_SESSION или базе данных, то не стоит его хранить в открытом виде. Это может быть только хеш от него, или закриптованный вариант.

Собственно, из URL'а украть ID сессии несложно, и немногим труднее это сделать с куками.

Способы защиты:

  1. Избегать сессий без кук
  2. Избегать посторонних серверных решений для аутентификации
  3. Проверять IP
  4. При особо важных действиях запрашивать пароль ещё раз
  5. SSL сертификат
  6. Вовремя и достаточно часто завершать сессии

Надёжный способ — хранить IP в сессии, и если он вдруг по какой-то причине стал отличаться, перестать выводить что-либо на страницу, можно даже принудительно завершить сессию.

Тем не менее, есть и недостатки — взломщик и пользователь могут сидеть за фаерволом с одного и того же IP, или же у юзера попросту может происходить динамическая смена IP прямо во время сессии.

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

Про завершение сессий — время их жизни следует выставлять минимальное, и всегда иметь кнопку выхода из аккаунта на сайте.

Вывод — данная уязвимость вторая по распространённости среди веб-сервисов, и используя все вышеперечисленные методы борьбы можно достаточно эффективно уберечь клиентов от подобного взлома. Ведь хакеру достаточно иметь ID сессии, и ему больше не понадобится ни пароля, ни имени пользователя, чтобы предстать в его образе.

3. XSS

Исчерпывающая и замечательная статья: habrahabr.ru/post/149152/

… но от себя хотелось бы добавить кое-что.

HTTP заголовки:

X-Content-Type-Options: nosniff
Блокирует загрузку неподтверждённых атрибутом скриптов. (type=«text/javascript», type=«text/css»)

X-Frame-Options: DENY
Запрещает встраивать данную страницу в iframe

Strict-Transport-Security: max-age=expireTime
Запрет на загрузку чего-либо по незашифрованному протоколу (HTTP)

Важное замечание, касающееся этой и предыдущей темы — httpOnly cookie.
Это стандарт был введён давно, но многими забывается или игнорируется. Делает он следующее: делает куки недоступными иными средствами, кроме HTTP. Его установка означает, что их нельзя будет получить средствами JavaScript.

alert(document.cookie);

httpOnly это седьмой параметр функции setcookie() в PHP.

4. Небезопасные прямые ссылки на объекты

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

Здесь проще сразу привести примеры:

  • Прямая ссылка на приватную фотографию в закрытом альбоме
  • Открытый номер кошелька в GET-запросе
  • AJAX запрос-ответ по userID, возвращающий все данные о юзере в JSON, которые фильтруются на стороне клиента (смешно, сам встречал)
  • Незакрытый просмотр/редактирование, например, своего профиля. В примере ниже, юзер с ID 3 может перейти на страницу профиля ID 1, и отредактировать его

http://site.com/profile/3
http://site.com/profile/1

Нельзя просто забывать проверить, тот ли юзер стоит перед нами, или нет.
Сюда же относится простая защита на количество неправильных попыток ввода пароля.

5. Небезопасная конфигурация

Говоря проще, это недостаточно или неправильно настроенный конфигурационный файл сервера/PHP/…
Сюда относятся:

  • Открытые логи
  • Не закрытый development mode (незакрытое профилирование запросов, stack trace)
  • Открытый конфиг. Не main.php, к примеру, а main.inc
  • Не иметь аккаунтов admin/admin. Даже на роутере в офисе.
  • Открытый доступ в папки images. Закрывается с помощью .htaccess или пустым index.html
  • И открытые папки вроде .git или .svn

Иммунитет даст:

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

Профилактика — сюда относится установка разных паролей на разные сферы (SSH, MySQL, бэкенды, панель хостера) и регулярная их замена
Так же, приложение должно иметь строгую архитектуру, где каждый разбирается — в проекте не должно быть следующего:

А что это за папка, которая лежит у нас в корне третий месяц?

6. Утечка чувствительных данных

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

Тест на уязвимость:

  • Хранятся ли у нас какие-либо данные о деньгах/номерах кошельков/состоянии здоровья в БД в открытом виде?
  • Также, в каком виде эти данные передаются по сети?
  • Свежие ли версии софта стоят?
  • Достаточно ли силён алгоритм шифрования, и часто ли происходит его обновление?

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

Пример #2: Простой сайт, не использующий SSL на всех своих страницах. Достаточно, чтобы сертификат где-то один раз порушился, чтобы злоумышленник смог стырить ID сессии, отслеживая трафик данных.

Пример #3: Хранить в БД незасоленные пароли.

Рекомендуется не автокомплитить такую информацию, и не кешировать страницы с ней.

7. Отсутствие контроля доступа к функциональному уровню

Заголовок подразумевает разграниченный доступ к определённым функциям приложения.

  • Не оставлять ссылки для тех, кому нет прав туда заходить
  • Иммунитет даст по дефолту снятие доступов для всех и со всего — принцип белого листа и deny(*).
  • Так же, не помешает проверка в важных местах кода в процессе выполнения действия — при вызове функции/метода поставить проверку ещё раз.

Сюда отнесётся так же простейшая уязвимость вроде подбора URL'а для админки и ответа от этой директории. Плохо, если хакер найдёт папку admin, и увидит форму логина. В таких случаях уместно закрывать директории по IP, или сессией и редиректами.

site.com/admin < site.com/highlevel

8. Подделка межсайтовых запросов (CSRF)

Один из самых малозаметных для разработчиков типов уязвимостей. В одиночку, как правило, несёт не много вреда, чаще всего урон от него можно почувствовать в связке с другими уязвимостями (XSS, невалидированные редиректы)

На самом деле, это мой любимый метод взлома сайта, и заслуживает целой статьи с подробностями, но какой же это тогда спидран?
Приведу ссылку на замечательное описание дыры на securitylab.ru

9. Использование компонентов с известными уязвимостями

Здесь всё предельно просто, поддерживать все подключаемые части проекта в актуальном состоянии, обновлять до последних стабильных версий, не юзать малопопулярные или любительские модули. Если стоит выбор — не использовать их в принципе.

10. Невалидированные редиректы

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

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

  • Не злоупотреблять редиректами.
  • Если пришлось, не использовать пользовательские данные в запросе (вроде success.php&user_mail=eeee@eee.com)
  • Рекомендуется перезаписывать урлы средствами сервера.

К примеру, вместо contacts.php?act=index/site -> contacts/index/site
Такие ссылки проще валидировать.

11. Кликджекинг

Из названия — «угон кликов». Над страницей сайт злоумышленника лежит прозрачный iframe, с помощью пресловутой социальной инженерии хакер заставляет пользователя сделать несколько определённых действий. Юзеру кажется, что он нажимает кнопки/формы на одном сайте, на самом деле всё подстроено так, что все действия выполняются на странице внутри iframe. Такое достигается путём создания одинаковых координат кнопок/форм на атакующем сайте и сайте-жертве.
Особенность в том, что пользователь сам не знает, что он вводит данные «не туда». Чтобы предотвратить такое, следует пользоваться тегом X-Frame-Options: DENY (см. выше), и простая каптча или повторный ввод пароля.

12. Фишинг

Популярный метод вытянуть логин/пароль из жертвы. Как правило, по особым базам данных жертв производится E-Mail рассылка, где пользователя от лица настоящего сайта побуждают к действию перейти на сайт.
К примеру, вместо yandex.ru это окажется yandx.ru, uandex.ru, yandex.nk.me и проч.
Внешне он выглядит точно так же, как наш сайт, на котором юзер разлогинен. Опять же, какими-либо средствами соц. инженерии злоумышленник просит жертву залогиниться, (на своём сайте), и просто-напросто получает логин/ пароль. Как правило, после ввода выдаётся что-то вроде сообщения об ошибке авторизации, и больше ничего не происходит.

От фишинга сейчас защищены даже браузеры, и большое количество антивирусов, но проблема остаётся актуальной. Во избежание «рутания» аккаунта ваших пользователей, просите их вводить пароль при особо важных операциях (перевод денег), или просите подтвердить аккаунт при помощи SMS.

13. PHP Include

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

В адресной строке видим запрос:
http://site.com/index.php?p=contacts.php
Уже всё яснее ясного, да? Как правило, внутри кроется примерно следующее:

<?
include($_GET['file']);
?>

Дальше ваша фантазия может играть сколько угодно:

site.com/index.php?file=../../etc/passwd%00
site.com/index.php?file=../apache/error.log # Сгенерировать ошибку в запросе с <?shell_exec($_GET['z'])?>
site.com/index.php?file=index.php # Завал рекурсией
site.com/index.php?file=images/2014/06/15/12.jpg # Ранее залитый шелл в запрещённой на исполнение директории может подключиться и сработать

Во избежание многих из этих ошибок, помните, что GET — только для получения данных, для всего остальное есть Master POST.

Автор: Darth_Saracen

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js