Не ленитесь фильтровать входные данные, даже если ваш сайт «никому не нужен».
Ставить самые свежие версии ПО иногда опасно, но и на старых сидеть не стоит, потому что вас сможет взломать любой человек, умеющий пользоваться поиском и скачивать специальные программы «для взлома сайтов».
Фильтровать нужно не только HTML-теги и кавычки, но также и другую полученную от пользователя информацию. Особенно важно следить за логикой и никогда не верить пользователю! Например, можно с помощью «средств разработчика» вашем браузере просто сделать видимой скрытую форму и нажать кнопку. Возможно, вы не предусматривали подобный сценарий на своём сайте.
По умолчанию вся информация сессий записывается в каталог temp. Если вы пользуетесь виртуальным хостингом, кто-то помимо вас может написать скрипт и считать данные сессий. Поэтому остерегайтесь хранения паролей или номеров кредиток в сессиях.
Если же всё-таки вам необходимо хранить подобные данные в сессии, то лучшей мерой будет шифрование. Это до конца не решает проблему, так как зашифрованные данные не на 100% безопасны, однако хранимая информация будет нечитабельной. Также вам стоит подумать о том, что данные сессии можно хранить в другом месте, таком, как база данных. В PHP есть специальный метод session_set_save_handler(), который позволит вам хранить данные сессий по-своему. Начиная с PHP 5.4 вы можете передать объект типа SessionHandlerInterface в session_set_save_handler().
Во время разработки приложения стоит обращать внимание на все виды ошибок, которые могут возникнуть, однако, от конечных пользователей их нужно скрывать. Если же ошибки отображаются пользователям, то это делает ваш сайт уязвимым. Таким образом, лучшим решением будет различная конфигурация для конечного сервера и сервера разработки.
На публичном сервере вам необходимо отключить такие опции, как display_errors и display_start_up_errors, а вот такие опции как error_reporting и log_errors, должны быть активны, чтоб все ошибки, возникшие у пользователей, записывались в логи.
Часто в PHP скриптах происходит подгрузка других файлов, таких как подключение к базе и многих других. Некоторые разработчики дают таким файлам расширение .inc. Такие файлы по умолчанию PHP не парсит. Если обратиться к ним по адресу напрямую, пользователь сможет увидеть текст данного файла. Если же хакеру удастся получить доступ к файлу хранящиму данные подключение к базе, то в последствии он может получить доступ ко всем данным вашего приложения. Так что всегда используйте расширение .php для подгружаемых файлов и храните их там, куда нет прямого пользовательского доступа.
Очень часто используемый тип уязвимостей. Для его использования взломщику нужно лишь иметь базовые знания HTML и JavaScript. В данном случае сервер не взламывается, а атака, по сути, направлена на пользователей уязвимого сайта.
Ключевая ошибка веб-разработчика в данном случае — недостаточная фильтрация полученных от пользователей данных.
XSS делится на две основные группы: «Активная XSS», это которая лежит где-то на сайте и ждёт свою жертву, а также «Пассивная XSS», которую взломщик посылает жертве, используя социальную инженерию.
Допустим, на сайте есть форма для ввода комментариев, которые сразу же отображаются после добавления. Злоумышленник может ввести комментарий, содержащий JavaScript код. После отправки формы, данные переправляются на сервер и заносятся в базу данных. После этого данные извлекаются из базы и новый комментарий отображается на HTML-странице, включая внедрённый JavaScript-код. Он может перенаправлять пользователя на какую-то вредоносную страницу или на фишинговый сайт.
Пример - На сайте пробуем ввести в текстовое поле фразу (см. ниже), жмём «Сохранить» и обновляем страницу. Находим мышку и пробуем ей подвигать возле почему-то пустого поля — появилось окошко? Поздравляю, мы нашли уязвимость!
" onmouseover="alert('XSS')" style="
Подобные уязвимости часто вылезают, когда система не фильтрует или фильтрует частично приходящую от пользователя информацию. Если вы пишете на PHP, то в нём есть функция htmlspecialchars(), которая позволяет частично решить проблему. Не нужно давать пользователю возможность использовать все теги, нужно также тщательно проверять, не вставил ли он что-то в разрешённый тег и не вышел ли он за пределы поля, как в примере выше.
Самое частое место, где можно найти пассивный XSS — это поиск. Попробуйте «поискать» у себя на сайте что-то вроде:
<script>alert(1)</script>
или
"> <script>alert(1)</script> <!--
Если выскочило окошко с цифрой «1», то ваш сайт подвержен таким атакам. Теперь взломщику достаточно послать вам особую ссылку, перейдя по которой вы отдадите ему полный доступ к своему аккаунту. Смысл тот же, что и в «Активной XSS», только теперь взломщику нужно «скормить» вам ссылку!
Такие уязвимости очень часто встречаются у начинающих веб-разработчиков. Для защиты нужно фильтровать кавычки и прочие спецсимволы, которые могут нарушить логику вашего запроса. Также, когда у вас есть число, обязательно явно приводите его к числу.
Атакующий использует различные трюки для получения конфиденциальной информации или совершения сделки без ведома жертвы. В основном это происходит на сайтах, где бизнес-логика строится на работе GET-запросов. GET-запросы должны использоваться только для получения доступа к информации, но ни в коем случае не для осуществления различного рода транзакций.
Следующий пример показывает как сайт может подвергнуться CSRF атаке:
<?php
if (isset($_REQUEST["name"], $_REQUEST["amount"])) {
// обработка запроса и перевод количества (денег) от авторизованного пользователя
// пользователю с именем переданным через GET запрос
}
Предположим, что Плохой Дядька хочет совершить CSRF-атаку над Алёной и сформировал специальный адрес, который отправил Алёне на e-mail:
<a href="http://example.com/process.php?name=Badman&amount=1000">Посети мой сайт!</a>
Если Алёна авторизована на сайте example.com и пройдёт по данной ссылке, то с её счёта на счёт дядьки будет переведено $1000. В качестве альтернативы плохой дядя может отправить и изображение, а в атрибуте src внести "плохой" адрес.
<img src="http://example.com/process.php?name=Badman&amount=1000" width="1" height="1"/>
Браузер не сможет отобразить данное изображение, так как его не существует, однако запрос будет совершён без ведома и участия Алёны.
В качестве дополнительных мер можно сгенерировать какой-то уникальный csrf-токен, который не должен знать злоумышленник, и прикреплять его к каждому POST-запросу. При входе пользователя в систему, можно генерировать случайный токен и записывать его в сессию. Поскольку все формы выводятся пользователю, данный токен нужно записывать в скрытое поле. Некоторые фреймворки вставляют этот токен в ваши формы автоматически.
Google подготовила сайт для демонстрации уязвимостей - XSS Game. Нужно пройти несколько заданий. Если затрудняетесь, то даются несколько подсказок.
Представлен сайт с поиском. Для начала введём поисковое слово, например, "cat". Выдаётся сообщение: "Sorry, no results were found for cat. Try again". При этом, также меняется адрес в адресной строке браузера https://xss-game.appspot.com/level1/frame?query=cat.
А что если попробовать ввести <h1>cat</h1>? Пробуем… Теперь выводится слово в виде заголовка, следовательно, нет проверки и обрезки специальных символов, и мы можем сделать простенькую инъекцию.
У нас есть два варианта. Например, можем сразу ввести адрес:
https://xss-game.appspot.com/level1/frame?query=<script>alert("HackCat")</script>
Подобный адрес можно послать пользователю, который выполнит вредоносный код. В нашем случае выскочит сообщение. Но вместо безобидной команды там может быть что-нибудь про document.cookie или другие плохие вещи.
Либо вводим в поиске команду:
<script>alert("HackCat")</script>
На втором уровне представлен форум, где можно оставлять комментарии. Введённые данные сохраняются на сервере, например, в базах данных. Если не проверять вводимые данные, то можно получить уязвимость.
Давайте сразу попробуем с <h1>cat</h1>. Получилось! Пробуем <script>alert("HackCat")</script>. Не прокатило! Форум экранирует наш тэг <script>. Но JS может быть вызван каким-нибудь элементом при разного рода событиях: onclick, onload, onerror и т.д. Можно попробовать встроить JS вместе с каким-либо элементом и вызвать его при событии с ним.
Попробуем, скажем, так. (В подсказках предлагают использовать img и атрибут onerror):
<img src="cat.png" onmouseover="alert('HackCat')">
Проводим мышкой над несуществующей картинкой и получаем уязвимость. Переходим на следующий уровень.
Можно было ввести и другие команды, например:
<button type="button" onclick="alert('HackCat')">Click Me!</button>
Тогда бы у нас появилась кнопка, нажав которую, мы снова переходим на следующий уровень.
Третий уровень предлагает нам посмотреть на фотки облачного дата-центра).
Не всегда у нас есть возможность вводить данные в поисковых строках. В данном случае мы можем только щёлкать по картинкам. Но при этом мы замечаем, что меняется адрес в адресной строке с изменением номера картинки - https://xss-game.appspot.com/level3/frame#3. А что если попробовать написать другое число? Вроде ничего интересного. А если вместо числа написать слово? Вводим адрес.
https://xss-game.appspot.com/level3/frame#cat
На этот раз видим надпись об ошибке Image NaN и незагруженную картинку. Смотрим код страницы, чтобы увидеть адрес картинки:
<img src="/static/level3/cloudcat.jpg">
Наше слово cat было добавлено в src картинки к слову cloud. А если пробовать закрыть тег, добавив спецсимволы? Попробуем так:
https://xss-game.appspot.com/level3/frame#cat' />
Выражением cat' /> будет закрыт атрибут src и при этом будет добавлен ".jpg' />". Значит, пора атаковать! В конец адреса добавим: <script>alert('HackCat');</script>:
https://xss-game.appspot.com/level3/frame#cat' /><script>alert('HackCat')</script>
Виды взломов сайтов и их предотвращение - CAPTCHA.ru