[Из песочницы] Для новичков. XSS и ошибки разработчиков на веб-сервисах

Сначала разберем, что такое XSS и его виды.


XSS — Cross-Site Scripting — Одна из множества уязвимостей веб приложений, которая позволяет внедрить вредоносный код, на страницу.

Есть 2 типа XSS:


  1. Пассивная — XSS, которая статично находится на странице
  2. Активная — XSS, которая динамично отображается на странице, при определенном запросе

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



Начнем с ошибочных представлений разработчиков:


  1. Разработчик думает, что XSS — это инъекция только в HTML-сущность и только. Данное ошибочное мнение складывается изо дня в день. На самом же деле, XSS могут быть не только в HTML, они могут быть почти везде, к примеру даже в картинке.


  2. Разработчик уверен, что отфильтровав спец символы, можно защититься от XSS. Данные мнение частично верно, но в большинстве случаев разработчики фильтруют только кавычки (< и >) и забывают про апострофы, которые потом могут попасть в атрибуты чего-либо.

А сейчас давайте разберем несколько типов атаки:


Обычный тип

Представим у нас есть PHTML (PHP + HTML) код




    
        Привет!
    
    
        Привет, !
    












Данный код выводит "Привет, незнакомец!", если нету GET параметра с именем name, но если же параметр есть, то тогда выведет "Привет, {$_GET['name']}!". При помощи GET-запроса, делаем запрос на наш скрипт: index.php?name=Admin. Выводит "Привет, Admin!".


Теперь попробуем вывести наш вредоносный код. Для этого делаем запрос: index.php?name=. Теперь нам выведет "Привет, Hacker!". Как видим, наш код document.write('Hacker') выполнился.



Так-же можно внедрять вредоносный код при внедрении в атрибуты. Для примера возьмем PHTML (PHP + HTML) код:



    
        Привет!
    
    
        Ваше имя: ">
    

Как видим, у нас выполнился код, где имя содержится в inpute (Текстовом поле). Теперь для внедрения нашего кода нужно всего лишь сделать запрос:index.php? name=»>. Как видим мы добавили»>`, тем самым закрыв атрибут и тэг:



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


Для защиты от данной уязвимости в PHP предусмотрена функция htmlspecialchars. Использовать её довольно просто — для этого в отрезок PHP-кода просто добавим обработчик htmlspecialchars Получается:



И наши XSS уже не работают.



Скриптовой тип

Представим, что у нас есть PHTML (PHP + HTML) код:




    
        Привет!
        
    
    
        ')">Удалить новость
    

Данный код выводит ссылку "Удалить новость", где ID новости передается в GET параметре id. При помощи GET-запроса делаем запрос на наш скрипт: index.php?name='); alert(1);//. Теперь при нажатии на ссылку, выведет наш alert(1), несмотря на htmlspecialchars. Это происходит из-за того, что htmlspecialchars не фильтрует по умолчанию одинарные кавычки.


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


Есть несколько способов защиты:


  • Тот же htmlspecialchars, но на этот раз с параметром ENT_QUOTES. Получается:



  • В данном способе используется функция addslashes. Она экранирует ковычки при помощи обратного слэша. Получается:



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


  • Оставить только числа. В данном способе используется преобразование в integer. Получается:

    Таким образом мы оставляем только числа.


Изображения

Многие, сейчас задаются вопросом «Почему же изображения и при чем они тут вообще?». В наше время все используют аватарки, картинки и т.п. Но неправильная фильтрация может повлечь за собой последствия! Итак, уязвимость заключается в том, что если фильтровать по типу «Изображение» или нет, то можно разрешить загрузку таких файлов, как SVG. Что такое SVG (.svg или .svgz)?


SVG — Язык для построения векторной графики на XML

Mime-Type для SVG: image/svg+xml


В чем же уязвимость?


SVG может отображаться в браузерах, но в чем же опасность? Как ни странно, но SVG может использовать JavaScript. Для этого просто нужно прописать в тэг svg атрибут onload. Пример:




    

Теперь, если загрузить данный файл на сервер (пусть будет путь http://site.ru/uploads/avatar.svg) и перейти по нему, то выполнится код из onload.


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


Фильтровать файлы по расширения (.png, .jpg, .jpeg) и после чего проверять их валидность.



Ссылки

К примеру у нас есть скрипт для защиты от OpenRedirect`a на PHTML (PHP + HTML):




    
        Переход на небезопасный сайт!
    
    
        ">Перейти на небезопасный сайт!
    

Уязвимость заключается в том, что мы можем использовать не только http || https-протоколы, а также javascript и data-протоколы. Для демонстрации перейдем по ссылке: script.php?url=javascript:alert(document.cookie);//. Теперь при нажатии на странице на ссылку, у нас вылезут наши cookie`s.


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


Фильтровать URL по regexу/^((http|https)\:\/\/)[a-zA-Z0–9.\/\?\:@-=#]+.([a-zA-Z0–9\&.\/\?\:@-=#])*$/is` и пропускать, только ссылки проходящие его


Рекомендации:


  1. Использовать специальный HTTPHeader: X-XSS-Protection
  2. Использовать специальный HTTPHeader: Content-Security-Policy

Ссылки на ресурсы:


https://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D0%B6%D1%81%D0%B0%D0%B9%D1%82%D0%BE%D0%B2%D1%8B%D0%B9_%D1%81%D0%BA%D1%80%D0%B8%D0%BF%D1%82%D0%B8%D0%BD%D0%B3
https://www.owasp.org/index.php/Cross-site_Scripting_%28%58%53%53%29
http://php.net/manual/ru/function.htmlspecialchars.php
http://php.net/manual/ru/function.addslashes.php
https://habrahabr.ru/post/157087/
https://ru.wikipedia.org/wiki/SVG
http://www.w3.org/Graphics/SVG/
https://habrahabr.ru/company/nixsolutions/blog/271575/
https://habrahabr.ru/post/168739/

Комментарии (1)

  • 21 октября 2016 в 14:26 (комментарий был изменён)

    +2

    >>> Как ни странно, но SVG может использовать JavaScript. Для этого просто нужно прописать в тэг svg атрибут onload

    В этом месте я перестал плакать.
    Сильно все намешали, коллега. Думаю, что эта статья новичка скорее запутает, чем систематизирует его знания.

© Habrahabr.ru