Защищаем сайт от атак на примере ХабраХабра

:

Рано утром Хабр «выкатил» своё новое обновление, и я с чистой совестью достаю эту статью из черновиков.
Вчера у меня случился epic fail и этот топик частично, включая строчку об апдейте выше, попал в паблик на пару секунд. За эти секунды топик успело плюсануть несколько человек.
Ещё раз, теперь публично, прошу прощения у администрации!
Совет остальным — НИКОГДА не храните в черновиках информацию вроде этой.

В последнее время в сети Интернет можно найти очень много пособий для «Начинающих хакеров», в которых подробно описываются все основные методы взлома сайтов. Думаете, веб-разработчики стали от этого умнее и предприняли все возможные методы для защиты? Я так не думаю.

В настоящей статье я хочу ещё раз поведать разработчикам о том, как ломают сайты, а чтобы вам не было скучно, я попутно буду ломать Хабр и подробно описывать, как я это делал. Мы рассмотрим такие интересные штучки, как «Активная XSS в профиле», «Бесконечное обнуление кармы», «Публикация топиков со значком 'Из песочницы'», «CSRF через Flash и дыру в Internet Explorer 6» и многое другое.

Все уязвимости уже исправлены. Ну или почти все. Поэтому, если вы найдёте очередную дыру, то пишите на support@habrahabr.ru — миф о том, что эту почту никто не читает всего лишь миф.

Вместо вступления


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

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

Часто разработчик думает, что ломать его сайт никому и в голову не придёт, поскольку там нет ничего интересного. Но взломщикам только что описанного типа это и не нужно, поэтому они легко находят уязвимость и делают дефейс (как правило, размещение своего сообщения вместо главной страницы, Чёрный Властелин уже делал так пару раз с ХабраХабром :-). Иногда же они даже не могут найти и простую уязвимость, поэтому используют готовые эксплоиты (таких людей ещё называют «Скрипт-кидди»). Таким образом, я уже могу дать вам несколько советов:

  • Не ленитесь фильтровать входные данные [об этом пойдёт речь дальше], даже если ваш сайт «никому не нужен».
  • Ставить самые свежие версии ПО иногда опасно, но и на старых сидеть не стоит, потому что вас сможет взломать любой человек, умеющий пользоваться поиском и скачивать специальные программы «для взлома сайтов».

Теперь давайте представим, что наш «персонаж» вырос и начал искать работу. Чем он будет скорее всего заниматься? Правильно, взломом за деньги.

Такой тип уже не представляет особой опасности для сайтов, где в самом деле нет ничего интересного. Работает же он теперь, в основном, «по заказу», часто в небольших группах.

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

Кстати, подобные «Эксперты» — это, как правило, всё тот же взломщик, который ушёл на пенсию и теперь зарабатывает на жизнь вполне мирным способом.

XSS или «Межсайтовый скриптинг»


Очень часто используемый тип уязвимостей. Для его использования взломщику нужно лишь иметь базовые знания HTML и JavaScript, вследствие чего применяется всеми типами описанных ранее «персонажей». Хочется отметить, что в данном случае сервер взламывать никто и не собирается, а атака, по сути, направлена на пользователей уязвимого сайта.

Ключевая ошибка веб-разработчика в данном случае — недостаточная фильтрация полученных от пользователей данных.

XSS делится на две основные группы: «Активная XSS», это которая лежит где-то на сайте и ждёт свою жертву, а также «Пассивная XSS», которую взломщик посылает жертве, используя социальную инженерию.

Посмотрим, чем нас может «обрадовать» Хабр. Британские учёные установили, что 95% взломщиков называют себя

" onmouseover="alert('XSS')" style="

Идём в настройки профиля и вводим эту фразу в поле «Настоящее имя». Теперь жмём «Сохранить» и обновляем страницу. Находим мышку и пробуем ей повозить возле почему-то пустого поля — появилось окошко? Поздравляю, мы нашли уязвимость!

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

Найти пример пассивной XSS на Хабре мне не удалось, потому опишу её суть на словах.

Самое частое место, где их можно найти — это поиск. Попробуйте «поискать» у себя на сайте что-то вроде

<script>alert(1)</script>

или
"> <script>alert(1)</script> <!--

Если выскочило окошко с цифрой «1», то ваш сайт подвержен таким атакам. Теперь взломщику достаточно послать вам особую ссылку, перейдя по которой вы отдадите ему полный доступ к своему аккаунту. Смысл тот же, что и в «Активной XSS», только теперь взломщику нужно «скормить» вам ссылку!

Проверяем другую принимаемую информацию


Фильтровать нужно не только HTML-теги и кавычки, но также и другую полученную от пользователя информацию.Особенно важно следить за логикой и никогда не верить пользователю! За примером далеко ходить не надо — заветная мечта любого тролля на Хабре, «Бесконечно обнуляемая карма», была вполне реализуема до сегодняшнего дня :-)

Если вы уже обнуляли карму и хотите сделать это ещё раз, то нужно с помощью «средств разработчика» вашем браузере просто сделать видимой скрытую форму и нажать «Обнулить»!

Для примера я создал «виртуальчика», слил ему карму, обнулил, опять слил, опять обнулил и так далее…

Справедливости ради стоит заметить, что мой милый виртуальчик был за это переведён в режим «Read-Only». Хорошо, что сам аккаунта не лишился.

Приведу ещё очень интересный пример. Когда публикуем новую статью или редактируем старую, то замена поля «topic_type» на «sandbox» позволяет получить плашку «Из песочницы».

Зачем это вам нужно? Ну не знаю, допустим, такие топики чаще плюсуют…

Что я могу посоветовать в данном случае? Ну конечно же, контролировать то, что вам шлют пользователи! Если вам шлют запрос на обнуление кармы, то проверьте, не обнулял ли пользователь её раньше, а если пользователь пытается опубликовать топик «из песочницы», то проверьте, в самом ли деле он оттуда.

SQL-инъекции


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

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

CSRF-уязвимости


Если Бубмбурум начинал своё покорение Хабра с супер-флешки, то я за ночь попал в ТОП5 пользователей благодаря найденной мною в прошлом году CSRF-уязвимости.

Прочитать мой топик можно тут. Сейчас же я пишу это потому, что недавно нашел ещё одну такую же и она могла приглашать на Хабр моих виртуальчиков с помощью пользователей, которые пользовались Internet Explorer 6. Стоит заметить, что таковых оказалось не много.

Для защиты вам нужно вставлять в каждую форму или важный запрос особенный csrf-токен, который не должен знать злоумышленник. Некоторые фреймворки вставляют этот токен в ваши формы автоматически.

Ссылки по теме


Википедия — XSS, SQL-инъекция, CSRF.

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