Защита web-приложений

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

Несмотря на активное использование приложений в Web, их безопасности уделяется недостаточно внимания. Вся система защиты сводится к рассредоточению: внешний сервер, сервер web-приложений, сервер базы данных, — все они находятся в разных зонах. Компоненты, используемые в разных зонах, имеют укрепленную операционную систему и хорошо сконфигурированы. В этом случае, если злоумышленнику и получается проникнуть на один из компонентов, то ущерб ограничен этим компонентом, т.к. между компонентами открыты исключительно те порты, которые необходимы для выполнения возложенной на них функции (рис. 1). Но, как я и говорил, многоступенчатые фильтры не принесут защиты от содержимого запроса. В случае приложений, работающих по технологии клиент-сервер, клиентская часть устанавливается на пользовательскую машину. При использовании web- приложений часть приложения загружается на машину пользователя, поэтому исследовать исходный код может кто угодно, собственно, сформировать необходимый запрос по результату исследования может тоже кто угодно. Web-приложения состоят из трех частей: представления, логики и данных. Уровень представления, получив запрос, передает его на уровень логики, который начинает обрабатывать запрос (возможно, с привлечением уровня данных), после чего передает результат снова на уровень представления. На каждую из трех частей атака может проводиться независимо. Уровень данных представляет собой хранилище информации и может опрашиваться логическим уровнем (рис. 2). Любой пользователь, в принципе, может запускать скрипт со своими параметрами. Для этого достаточно отправить на сервер специально сформированный запрос. Приведу пример такого запроса, в адресной строке пишется следующее:

httр://www.sa-sec.org/test.php?id=23&format=html.

Файл test.php выполняется на удаленном сервере включая параметры справа от знака вопроса. Если test.php представить в качестве исполняемого файла для Windows (test.exe), то результат оказался бы таким:

C:\ test.exe /id:23/fоrmat: html

Это типичный межсайтовый скриптинг, о котором, помнится, я уже писал на страницах КГ. Защитой от такого рода атак может быть хороший программинг под Web — для этого разработчик должен хорошо проверить имена и значения параметров. Конечно, на практике до этого не доходит. Вдобавок полностью игнорируются многочисленные элементы: идентификационные маркеры (Cookie), заголовок HTTP, информация о сеансе в URL, скрытые поля в исходном тексте и т.д. Поскольку протокол HTTP не содержит никакой информации о статусе пользователя, злоумышленник — в зависимости от приложения — может, к примеру, путем изменения маркера (Cookiе Poisoning, Cookie Stealing) или информации о сеансе в URL получить доступ к открытому сеансу другого пользователя и тем самым к его данным без имени и пароля. Изменение значений скрытых полей в исходном тексте также не представляет труда. Задачу упрощают так называемые "посредники перехвата", работающие на компьютере злоумышленника и заметно упрощающие манипуляции с перечисленными параметрами. Таким образом, для разработки надежного приложения программист должен исходить из того, что злоумышленник в состоянии манипулировать любыми значениями. Дополнительно необходимо проверить поля ввода на наличие специальных символов и сценариев, поскольку они — если достигнут сервера баз данных — могут вызвать запуск специальных функций или обеспечить доступ к оболочке через внешнюю программу. Так, простая кавычка (') в комбинации с командами SQL в поле ввода способна привести к нежелательным действиям с внутренней базой данных. Еще одним возможным сценарием является атака, когда некорректные данные представлены в зашифрованной форме. Если злоумышленник запускает сценарий на стороне клиента (Cross-Site Scripting), специальные символы будут интерпретированы еще позже, когда их выведет, интерпретирует и выполнит браузер ничего не подозревающего пользователя. Для защиты от переполнения буфера должна выполняться проверка длины. Итак, программист должен, с одной стороны, проверять, не манипулировал ли злоумышленник параметрами, заданными приложениями Web, а с другой — не содержат ли поля ввода неразрешенных данных: к примеру, инжекций SQL или команд, сценариев для выполнения на стороне клиента или переполнения буфера.

Компании не должны полагаться на сторонних разработчиков в том, что последние будут использовать надежное программирование. Большинство учитывают некоторые из общих рекомендаций, и то весьма поверхностно. Посему и приложения на выходе не отвечают всем требованиям безопасности. К тому же, надежное программирование достаточно сложно, а, следовательно, дорого. В любом случае приложение должно адекватно обрабатывать "мирные запросы". Это значит, что, допустим, апостроф в имени пользователя S'nams не должен распознаваться как попытка провести инжекцию SQL (рис. 5). Поэтому каждый раз значение поля следует обрабатывать индивидуально. При покупке готовых приложений компании должны проводить обязательный аудит кода для поиска и устранения потенциально опасных мест, иначе это может вылиться в весьма неприятное положение дел со всеми вытекающими последствиями. Альтернативой данному методу является использование брандмауэров для web-приложений (Web Application Firewall — WAF). Такого рода брандмауэр устанавливается перед web-приложением и предоставляет гораздо более расширенные возможности, нежели обычные программные брандмауэры для системы. Отличие от классической технологии заключается в том, что WAF интерпретирует защищаемые приложения Web с их отдельными страницами, полями ввода, значениями параметров и маркерами Cookie. WAF в состоянии контролировать все объекты, которые могут быть доступны пользователям, вводимые URL, а также параметры запросов GET и POST. Допускается возможность только тех URL, которые могут принадлежать тому или другому объекту. Также брандмауэр не позволяет пользователям запускать не относящиеся к ресурсу объекты — например, логи или системные журналы на сервере. Следует контролировать отклики, т.к. в них может содержаться описание ошибки — это описание может содержать достаточно важную информацию. Заголовок сервера, где в стандартной конфигурации сервера Web указан тип сервера (к примеру, сервер: Apache 2.0.54 (UNIX), mod_ssl/2.0.54 OpenSSL/0.9.7a DAV/2 SVN/1.2.0-dev), переписывается в отклике большинства WAF, чтобы злоумышленник не мог получить этих сведений таким простым способом.

Возможны два подхода к решениям обеспечения безопасности — в соответствии с положительной и отрицательной логикой безопасности. В последнем случае определяется лишь то, что запрещено — все остальное разрешено, как, например, в антивирусном сканере. WAF снабжаются заранее составленными черными списками, содержащими схемы распространенных типов атак. Тем самым обеспечивается защита от многих известных атак, базирующихся на этих схемах, поэтому нет необходимости в знании и конфигурировании всех параметров. Чрезвычайно важная функция — исключение отдельных полей ввода перед проверкой для предотвращения неверных положительных распознаваний. В некоторых приложениях Web — к примеру, в техническом дискуссионном форуме — при определенных обстоятельствах может понадобиться разрешение возможности ввода кодов HTML или сценариев. Положительная, известная также как белый список, логика предполагает определение того, что можно — все остальное запрещено. Хотя это и означает значительные издержки на конфигурацию, но в результате обеспечивается существенно более последовательная защита, в том числе от неизвестных типов атак. WAF должен поддерживать комбинацию обоих типов логики. И наиболее эффективен WAF тогда, когда может соответствующим образом интерпретировать приложение Web, т.е. положительная логика преобладает. Основой этого является создание свода правил — так называемой политики. Возможны два подхода: динамический и статический. При динамическом администратор определяет действительные страницы входа и работу WAF в реальном времени.

Для каждой запрошенной пользователем страницы содержащиеся в коде HTML ссылки включая определенные в URI величины добавляются в динамически создаваемое правило. К сожалению, для более сложных приложений, когда на стороне клиента используется JavaScript, эту функцию часто нельзя осмысленно применять, потому что JavaScript позволяет генерировать на клиенте вызываемый URL с передаваемыми параметрами. Как следствие администратор должен определять эти URL как исключение — причем речь идет лишь об одном из нескольких примеров, когда JavaScript на клиенте в случае динамического варианта вызывает проблемы. Поэтому наиболее распространен статический вариант. При статическом подходе администратор создает правило до применения WAF. Этим процессом можно управлять вручную или автоматизировать при помощи определенных инструментов. Например, WAF можно прозрачно включить в поток данных для предварительного протоколирования трафика. На основании полученных данных администратор путем ввода надежных IP-адресов или их диапазонов и определения промежутка времени может описать в политике все варианты разрешенного доступа. Еще одним инструментом является "крот" (crawler). Он должен начиная с некоторой стартовой страницы автоматически отследить все ссылки и за короткое время составить список всех URL включая поля ввода, статичные значения пунктов списка, селективные кнопки и перечни выбора, на основании которых можно будет сформировать политику. Важная функция — анализ "кротом" JavaScript.

Дополнительно должна быть предусмотрена возможность определения пути навигации, по которому может быть вызвана указанная страница. Если, к примеру, задано, что страница z.html должна быть достижимой лишь после того, как пользователь запросил сначала страницу x.html, а потом y.html, то WAF блокирует запрос непосредственно к z.html. В этом случае говорят о "потоках", для которых определяются объекты отправителя и получателя. Ряд производителей предлагают собственный браузер для тонкой настройки, который также оказывается полезен при формировании политики. Поскольку правило не должно генерироваться динамически, статический подход значительно более производителен. Проверка того, было ли статическое значение в запросе HTTP несанкционированно изменено, для большинства WAF не представляет проблемы. Однако при использовании статического подхода WAF должны защищать также от изменений динамических значений, генерируемых на сервере. Это динамическое значение, генерируемое приложением во время выполнения, встречается, к примеру, в URL или в скрытых полях. Злоумышленник может просто изменить его и отправить в следующем запросе HTTP приложению Web. В результате, к примеру, товар будет помещен в корзину покупателя по более низкой цене (рис. 3). Другие приложения для однозначной идентификации пользователя применяют идентификаторы сеанса, которые генерируются на сервере в качестве динамических параметров. Если злоумышленнику удается добраться до идентификатора сеанса другого пользователя, он получает доступ к пользовательскому сеансу и тем самым к его данным без знания имени пользователя и пароля. Для защиты ландшафта ИТ можно настроить WAF таким образом, чтобы он, к примеру, удалял этот динамический параметр из отклика.

Еще одна важная задача WAF — проверка маркеров Cookie. WAF должен предотвращать попадание в приложение Web модифицированных пользователем маркеров (Cookie Poisoning). Если злоумышленнику удастся это сделать, не исключено, что он, как и в предыдущем примере с идентификатором сеанса, попытается получить доступ к сеансу другого пользователя. Одним из вариантов проверки в WAF является помещение зашифрованных и подписанных имен и содержимого всех маркеров пользователя в дополнительном сеансовом маркере, который имеется только в памяти у клиента. Если маркеры передаются браузером приложению, как это происходит в случае каждого запроса HTTP, WAF посредством дополнительного сеансового маркера распознает, изменил ли злоумышленник один или несколько маркеров. К сожалению, некоторые приложения меняют содержимое маркеров и на стороне клиента. Поэтому важно, чтобы маркеры таких приложений могли исключаться перед проверкой. Другой вариант — шифровать все маркеры приложений. При этом, как описано выше, отдельные маркеры могут перед шифрованием исключаться. Когда приложение изменяет на клиенте содержимое отдельного маркера, оно должно быть представлено открытым текстом. Большинство WAF работают в качестве обратного посредника. Они принимают от клиента запрос HTTP вместо сервера Web или балансировщика нагрузки, анализируют его соответствие политике и организуют новое соединение HTTP, наделенное собственным IP-адресом, с сервером Web или балансировщиком нагрузки (рис. 4).

Поэтому для регистрации IP-адресов отправителя на сервере Web необходимо, чтобы WAF мог передавать дальше исходный IP-адрес клиента, к примеру, в заголовке X-Forwarded-For-Header (XFF). Терминирование SSL и аппаратное ускорение шифрования и дешифрования включая согласование ключа должно поддерживаться в любом фильтре приложений, иначе анализу оказываются доступны только незашифрованные данные. Пассивный режим мониторинга, когда запросы злоумышленника не блокируют, а только отмечаются в отчетах, полезен не только при вводе в эксплуатацию, но и в случае высокочувствительных приложений. Тем самым остается по крайней мере возможность получения информации обо всех атаках на приложение Web и сервер Web без прерывания работы приложения.

Это все, что я хотел рассказать про защиту приложений web. Это, пожалуй, является одной из самых сложных задач, т.к. защитить ресурс от XSS или инжекций SQL крайне сложно, но можно:).

P.S.: Благодарю компанию F5 за информацию, на которой основывается этот материал.

Евгений Кучук, q@sa-sec.org, SASecurity group


Компьютерная газета. Статья была опубликована в номере 02 за 2009 год в рубрике безопасность

©1997-2024 Компьютерная газета