PHP. Основы безопасности сайта
Все предыдущие примеры были безобидными. То, что мы сейчас делаем, по сути, никакого вреда особо сильного не несет. А вот представьте, если сюда будет встроен какой-нибудь фрейм. Например, урок по основам безопасности сайтов :)
Вставим фрейм:
<iframe allowfullscreen="" frameborder="0" height="315" src="https://www.youtube.com/embed/hETK-ohKbhw" width="560"></iframe>А ведь согласитесь: во фрейме может быть какая-нибудь плохая вещь. Кто какую плохую вещь может предложить завернуть?
*ответ на вопрос из чата* Да, был пример, где сайт переворачивался. Например :)
<style type="text/css">body { transform: rotate (180deg); }</style>Что случится, когда код отработает? О! Перевернул. Нормальный сайт, правда? :) Теперь перевернутый сайт – это общее для всех пользователей – любой, кто сюда зайдет, будет видеть это безобразие.
Это безобидные варианты XSS-атаки, они немножко издеваются над пользователем. Можно еще анимацию добавить, например.
Есть нехорошие варианты XSS-атак. Когда внедряется тег-скрипт, который создает картинку и, допустим, у этой картинки прописывает такой путь, который гет-параметрам отправит куки по ссылке на другой домен. Этого показывать не будем.
Ещё XSS-атаки неожиданно настигают, когда мы не очень аккуратно работаем с гет-параметрами.
*вопрос из чата* XSS – это, по сути, внедрение js-а на сайт. – Да, XSS – это кросс сайт скриптинг, межкроссдоменные запросы, которые вставляют картинку, которая подтягивается с другого сайта.
*разговор с чатом* В любой CMS отключены эти баги. – Очень сомнительно, особенно, если в CMS дописываются новые модули. Понимаете, WordPress от дырок закрыли, а вот плагины – далеко не все.
*ответ на вопрос* То есть XSS может просто повертеть сайт, а SQL-инъекции повертеть БД. – В чем заключается проблема внедрения такого тега? Представьте, что здесь будет написан тег-скейп, и у нас есть глобальная переменная «документ» java-скрипте. А вот у «документа» есть вложенный параметр, который называется «куки», т.е. это те куки, которые установлены для данного домена, которые доступны на стороне клиента. И этот массив успешным образом преобразуется в строку. Это вообще не несет в себе никакой проблемы. И поэтому есть очень нехороший вариант, который может с пользователем случиться. То есть будет в java-скрипте сделана новая картинка, и у этой картинки будет установлен какой-нибудь путь, который равен, условно говоря, какому-нибудь домену. То есть, соответственно, что эта штука сделает? Вот представьте, вы все зайдете в свой аккаунт в ВК, а у Вас выполнится вот такой вот скрипт, который отправит ваши куки на сайт.ру. Вот, кто как думает, что тогда произойдет, если такое вдруг случится? *варианты из чата* «Заводить новый». «Пароль свиснут». – На продвинутых сайтах куки доступны только из php, из js-а они не даются. Но тем не менее, на менее крутых сайтах, которые не так продвинуты в безопасности, выполнение такого кода приведет к тому, что Ваши куки отошлются на другой сайт, и будет всё очень грустно. Это уже не забава, это уже воровство данных идет.
При этом эти теги могут попасть сюда не только из базы данных, а даже из get-параметра какого-нибудь. Представьте, что здесь есть какое-то поле, т.е. мы, например, хотим поставить какой-нибудь get-параметр в hidden-поле или ещё куда.
*вопрос из чата* А если они зашифрованы? – Смотрите. Какая разница: зашифрованы куки или нет? В браузере есть куки. Если их украсть и поставить в curl, то curl отправит точно такие же зашифрованные куки, какие были нужны. Главное, что я создам ровно такой же запрос, как создал бы пользователь из этого своего браузера.
Эти теги на страницу иногда попадают через неудачно подставленные гет-параметры, но это тема отдельная. Сейчас давайте пофиксим хотя бы нашу беду.
Проблема заключается в том, что мы наивно добавляем данные, которые получили от пользователя в базу, никак их не обрабатывая. Какой конкретно символ вредит в данных примерах? Да, все верно – значок «меньше». С ним надо что-то делать. Есть две специальных функции, они работают по-разному: это «strip_tags» и «htmlspecialchats».
Давайте попробуем сначала провернуть простую функцию «strip_tags» и посмотрим, что после этого получится. Пишем: name присвоить strip_tags от name. И пишем: text присвоить strip_tags от text. Эта функция занимается тем, что она вырезает отсюда все html-теги, которые найдет. html-тег любой чем характеризуется? Знак меньше, знак больше. То есть его вычислить скрипту не составляет никакого труда. Попробуем провернуть нехороший запрос. Я его отправляю. Кто как считает, что после этого произойдет, если я отправлю такой запрос? «Центр останется». «Код преобразится». Смотрите, этот скрипт спокойно вывелся на экран и никак не отработал, потому что он в базу был добавлен без всяких тегов. Это один из самых простых вариантов, когда мы все теги, которые пользователь нам пишет, просто берем и вырезаем. Любые данные, которые заносите от пользователя в базу, надо так обработать. Просто на 100% обязательно.
*вопрос из чата* Если тег не обработан, то он в базу не добавится. – Если тег не обработан, то он в базе окажется. Эта функция освобождает данные от тегов, она их просто выкидывает. Если пользователь должен уметь как-то оформлять комментарий, то это задача сложнее, там категорически запрещено вообще расставлять теги. Там должны ставиться псевдо-теги, маркап-синтаксис. Можете погуглить, что это такое. Это когда мы ставим квадратные теги и на этапе вывода уже работает пепроцессор, которые превращает это в обычные теги.
И вот теперь посмотрим другой пример. Выглядит так же, только вместо «strip_tags» будет присутствовать «htmlspecialchats». Кто знает, что такое спец символы в html, кто хоть раз их видел? Знак амперсанда (&), какое-нибудь название и «;». Давайте сейчас сделаем какой-нибудь мини-пример, для сравнения. На страничке «1.html» сравним две строки. Одна строка будет выглядеть так:
<h1>Ура</h1>
а вторая строка будет выглядеть вот так:
<h1>Ура</h1>
lt – это знак «меньше», только написанный с помощью спец символа, gt – знак «больше», тоже написан спец символом. Чем будут отличаться эти строчки с точки зрения их работы. Вы даже теперь в чат умеете писать значки «меньше» :) А до этого все писали значок «меньше» настоящий и получали экранирование. В чем разница первой и второй строк? Они сработают обе, но сработают по-разному. Когда мы пишем тег по-настоящему, он является управляющей конструкцией в html, т.е. он управляет созданием разметки, говорит: «здесь мы начинаем контейнер тега «h1», здесь мы этот контейнер заканчиваем». А < – это тупо вывод значка «меньше» на экран. Вторая ситуация – безобидная. Мы просто-напросто увидели на экране вот эти h1-/h1, но они реально никак не увеличили размер текста, т.е. это не стало тегом h1. Просто вывод на экран. И, соответственно, возникает очень логичный вариант защититься от внедрения тегов свою страницу: во всех данных, которые вы получили от пользователя, нужно сделать замену. Все значки «меньше» вы заменяете на «<», а все значки «больше» - на «>».
Вот кто как думает: есть в html-е ещё какая-нибудь нехорошая вещь, которая теоретически, помимо значков «меньше» и «больше», является потенциально опасной? Она на самом деле не очень опасная, но тем не менее, её тоже рекомендуют экранировать. Да, совершенно верно, «кавычки».
Продолжение смотрите в видео.
Всё это — минимальные возможности PHP. Более крутые приемы и лайфхаки — от практикующих программистах — на курсах и стажировке. Смотрите на сайте!