29 2. КОНСТРУКТОРСКАЯ ЧАСТЬ 2.1. Описание алгоритма работы программы Программа состоит из трех основных модулей: Непосредственно движок, выполняющий основные функции приложения: определение карты сайта, поиск уязвимостей. Модуль, отвечающий за сборку информации о проведенной проверке и подготовку отчета. Пользовательский графический интерфейс (GUI). Работа движка делится на три основных этапа: Создание карты сайта Поиск доступных форм для ввода данных Анализ найденных форм При этом нельзя четко разделить время выполнение первого и второго этапов. Дело в том, что во время поиска доступных форм существует вероятность нахождение страницы, которой не было найдено во время поиска внутренних ссылок на этапе создания карты сайта. Такой подход позволяет сэкономить время и трафик. На каждом этапе для ускорения работы выполнение задач происходит параллельно с использованием многопоточности и шаблона проектирование пул потоков (thread pool). Каждому потоку ставится в соответствие окно браузера, которое выполняет команды, переданные из программы. Важно отметить, что движок не имеет тесных переплетений с модулем пользовательского интерфейса и модуля подготовки отчета, что позволяет реализовать удобный для пользователя интерфейс и формат отчета. Взаимодействие движка с остальными модулями осуществляется с помощью функций обратного вызова (callbacks) и реализованного для этих целей
30 интерфейса EngineListener. EngineListener состоит из 4-х функций обратного вызова: public void onBrowsersReady() – вызывается, когда все необходимые для работы браузеры запущены; public void onCreateMapEnds() – вызывается, когда формирована карта сайта; public void onXssPrepareEnds() – вызывается после завершения анализа карт сайта на наличие xss-уязвимостей. public void onXssAdded(XssStruct xssStruct) – вызывается после обнаружения xss-уязвимости. В качестве аргумента принимает xssStruct – объект, содержащий подробную информацию о виде xss-уязвимости и о месте ее нахождения. 2.2. Описание алгоритма работы основных задач Все основные задачи данной программы для ускорения работы выполняются параллельно и являются наследниками абстрактного класса BrowserRunnable, который, в свою очередь, реализует интерфейс Runnable. BrowserRunnable отвечает за связка потока и окна браузера, а интерфейс Runnable является интерфейсом многопоточности. Все задачи находятся в пакете Tasks. LinkFinder – класс, отвечающий за поиск ссылок на странице и формирование карты сайта. XssPreparer – класс, отвечающий за поиск форм, где потенциально могут появится уязвимости для проверки, и разделение потенциальных уязвимостей на два типа: отраженные (reflected) и хранимые (stored). ReflectedXssChecker – класс, отвечающий за поиск отраженных (reflected) xss-уязвимостей. StoredXssChecker – класс, отвечающий за поиск хранимых (stored) xss- уязвимостей.
31 Диаграмма классов изображена на рис. 1. Рисунок 1 - Диаграмма классов package Task 2.2.1. Создание карты сайта. LinkFinder Одной из важнейших задач, решаемых данным приложением, является создание карты сайта. Карта сайта аналогична разделу «Содержание» обычной книги. Используется как элемент навигации. В карте сайта представлен полный перечень разделов и/или всех страниц, имеющихся на сайте. [8] Если допустить ошибку на этом этапе, даже имея абсолютно полный список всех существующих xss-инъекций и бесконечное время для того, чтобы их опробовать, нельзя будет гарантировать отсутствие уязвимостей. Получив доступ к HTML-коду страницы, LinkFinder начинает анализировать страницу на наличие ссылок, т.е. тега . Выбрав все ссылки на странице, начинается парсинг атрибутов тега . Если у тега находится атрибут href, его значение анализируется: проверяется, является ли он внутренней ссылкой.
32 Не маловажным является и тот факт, что в качестве атрибута href может выступать не только ссылка на страницу, но и ссылка на конкретный файл, например, документ Microsoft Word, имеющий расширение .doc, или ссылка на фильм, имеющий большой размер. Для того, чтобы не совершать ошибок, влекущих огромные потери трафика и практически бездействие потока, занимающегося ненужным скачиванием файла, значение атрибута href также необходимо фильтровать. Было принято решение отсеивать ссылки, которые имеют непустое окончание, и при этом не оканчиваются на самые популярные форматы web страниц: “.html”, “.htm”, “.php”, “.phtml”, “.shtml”, “.asp”, “.aspx”, “.xml”. Если ссылка была найдена, и она прошла механизм фильтрации, то от нее отрезается часть строки с аргументами, если таковая имеется, и ссылка добавляется в специальную структуру данных LinkContainer. LinkContainer является наследником стандартной структуры данных JDK (Java Developer Kit) LinkedHashSet. LinkedContainer обеспечивает существование единственного экземпляра данной ссылки, чтобы избежать ненужных повторений, и позволяет хранить ссылки в порядке добавления. После успешного добавления LinkContainer вызывает callback-функцию onLinkAdded(String url) интерфейса OnLinkContainerCallback. В роли callback- объекта выступает основной движок программы Engine, который, в свою очередь, создает новую задачу LinkFinder с полученным URL и добавляет ее в пул потоков. 2.2.2. Реализация поиска форм. XssPreparer XssPreparer отвечает за поиск форм, где потенциально могут появится уязвимости для проверки, и разделение потенциальных уязвимостей на два типа: отраженные (reflected) и хранимые (stored). Для того, чтобы осуществить поиск форм, было принято решение заполнять все элементы (,
33 странице, заданным значением. Selenium WebDriver позволяет выполнить эту операцию, но не гарантирует выполнения команды, и, к тому же, занимает длительное время. Чтобы этого избежать, был разработан скрипт на языке javascript. Этот скрипт выполняется в браузере, и заполняет все формы специальным значением, которое не могло бы появится при естественной работе web-приложения. После заполнения элементов, формы поочередно отправляются. Затем, на странице ищется специальное значение, которое было заполнено на предыдущем шаге. Если это значение найдено, можно сделать вывод о том, что искомая форма найдена. Остается лишь определить тип потенциальной уязвимости. Для этого достаточно проанализировать URL. Если URL содержит параметры со введенными на предыдущем шаге значениями, то был произведен GET-запрос, и стало быть, имеет место потенциальная отраженная (reflected) xss-уязвимость. Если же URL не содержит параметров, или ни один параметр не содержит специального значения, делаем вывод, что в таких условиях возможна только хранимая (stored) xss-уязвимость. После обнаружения информация о потенциальной уязвимости попадает в специальный контейнер для хранения XssContainer, который является наследником LinkedHashSet. Для того, чтобы отслеживать процесс добавления потенциальных уязвимостей, был реализован интерфейс XssContainerCallback, который вызывает метод onXssAdded всякий раз, когда в структуру добавляется потенциальная уязвимость. 2.2.3. Реализация поиска отраженных xss-уязвимостей. ReflectedXssChecker Класс ReflecXssChecker занимается сканированием заданного URL на наличие отраженных (reflected) xss-уязвимостей.
34 Существует решение «в лоб». Открываем страницу, поступившую для проверки, заполняем форму, которая вызывает сомнения с точки зрения безопасности, xss-инъекцией, отправляем эту форму и следим за реакцией браузера. Такой подход имеет ряд недостатков и избыточностей. Чтобы работа велась наиболее оптимально, было решено совершать подстановку xss- инъекций непосредственно в адресную строку браузера, заменяя значения параметров, которые вызывают сомнения с точки зрения безопасности. Такое решение позволяет примерно вдвое сократить трафик, расходуемый на эту задачу, и во сколько же раз ускорить время выполнения данной задачи. В качестве скрипта, который является индикатором обнаружения xss- уязвимости был выбран скрипт: location.hash=10; Этот скрипт добавляет к текущему URL постфикс #10. Выбор именно этого скрипта связан с легкостью и скоростью его выполнения в браузере, в отличии от тех скриптов, которые вызывают всплывающее окно (alert() или confirm()). К тому же, данный скрипт не содержит дополнительных спец- символов, например ковычек, что увеличивает шанс на срабатывание xss- инъекции. Следует так же отметить поддержку различной глубины поиска. Сам список инъекций хранится в трех текстовых файлах. Каких либо ограничений на редактирование или просмотр этих файлов нет. Инъекции рассортированы по файлам в соответствие с популярностью их появления в web-приложениях. Первый файл хранит самые популярные и простые xss-уязвимости и соответствует поверхностной проверке. Xss-инъекции из первого файла в сочетании с xss-инъекциями из второго файла образуют среднюю глубину поиска. В последнем файле содержатся наиболее специфичные и изощренные xss-инъекции. Таким образом, инъекции из всех трех файлов в совокупности составляют достаточную для глубокого поиска базу.
35 2.2.4. Поиск хранимых XSS-уязвимостей. StoredXssChecker В отличие от отраженных xss-уязвимостей, которые возникают в результате выполнения GET-запроса, хранимые xss-уязвимости являются следствием сохранения скрипта в базу данных. Каждый, хоть сколько-нибудь грамотный web-разработчик понимает, что вносить данные в базу необходимо с помощью POST-запроса, чтобы не позволить поисковому роботу вносить изменения в базу данных, а также поддерживать безопасность. Таким образом, в данном случае нет возможности сократить потребляемый трафик путем непосредственного перехода на нужную страницу, меняя только параметры. Приходится сначала заходить на страницу, на которой находится форма, заполнять форму необходимой xss-инъекцией, отправлять форму. После отправки формы, приложение может перебросить пользователя на другую страницу. Эти ситуации отслеживаются, ожидается полная загрузка страницы. После загрузки страницы остается лишь проверить, был ли выполнен скрипт. В случае, если скрипт исполнился, форма и xss-инъекция запоминается в специальную структуру XssContainer. При выполнении скрипта продолжать поиск на данной странице бессмысленно, поскольку всякий раз, когда браузер будет отправлять форму, будет выполнятся скрипт, который уже находится в базе данных web-приложения. Поэтому рекомендуется, после устранения изъяна еще раз запустить тестирование.