Коллектив авторов - Защита от хакеров корпоративных сетей
Протокол HTTP и язык разметки HTML
В приложениях Интернет много ошибок, основанных на неверных предположениях о работе сети. Часть из них обусловлена дезинформацией, но большинство – ошибками программирования из-за недостаточного знания программистами принципов работы протокола передачи гипертекстовых файлов HTTP (Hypertext Transfer Protocol). (HTTP – протокол уровня приложений для распределенных информационных систем гипермедиа, позволяющий общаться системам с различной архитектурой. Используется при передаче HTML-файлов по сети страниц WWW и языка гипертекстовой разметки HTML (HyperText Markup Language). Язык HTML – стандартный язык, используемый для создания страниц WWW).
Самая большая ошибка, которую допускают программисты, – необоснованное доверие заголовкам запроса в HTTP-запросе и вера в них как в средство обеспечения безопасности. Заголовок запроса ссылки Referer в HTTP-запросе содержит адрес страницы, на которой находилась ссылка на запрашиваемый документ. Заголовок запроса Referer поддерживается клиентом в клиентских настройках. Так как он создается клиентом, то его можно легко фальсифицировать. Например, при Telnet-обращении к 80 порту (HTTP-порт) Web-сервера можно набрать следующее:
GET / HTTP/1.0
User-Agent: Spoofed-Agent/1.0
Referer: http://www.wiretrip.net/spoofed/referer/Видно, что в заголовке указана фальсифицированная ссылка и подложный агент пользователя. (В сетях агент пользователя (user agent) – прикладной процесс OSI, представляющий пользователя или организацию, который создает, передает и обеспечивает доставку сообщений для пользователя.) Единственно, чему можно доверять из переданной пользователем информации, – это IP-адресу клиента. (Хотя и он может быть фальсифицирован. Подробнее об этом сказано в главе 12.)
Другой недостаток HTTP – зависимость от ограничений представления информации средствами HTML. Зная это, многие разработчики предлагают пользователям выбирать данные из списка (например, из трех элементов). Конечно, совсем не обязательно ограничивать пользователя списком данных, заданным разработчиком. Однажды автор наблюдал достаточно ироничную ситуацию, когда сотрудник Microsoft предлагал использовать списки как эффективный метод борьбы с непредвиденными данными пользователя. Это предлагал человек из группы разработчиков SQL Server, не входивший в группу обеспечения безопасности или разработки Web-решений. От него нельзя требовать больше, чем знание внутренней логики работы SQL-сервера.
Рассмотрим пример HTML-формы, подготовленной приложением:<FORM ACTION=”process.cgi” METHOD=”GET”>
<SELECT NAME=”author”>
<OPTION VALUE=” Ryan Russell”>Ryan Russell
<OPTION VALUE=” Hal Flynn”> Hal Flynn
<OPTION VALUE=” Ryan Permeah”> Ryan Permeah
<OPTION VALUE=” Dan Kaminsky”> Dan Kaminsky
</SELECT>
<INPUT TYPE=”Submit”>
</FORM>В HTML-форме описан список, составленный из имен некоторых авторов. Получив HTML-форму, клиентское приложение разрывает соединение, анализирует полученную HTML-форму и предъявляет ее пользователю. После выбора из списка автора клиентское приложение посылает отдельный запрос на Web-сервер с приведенным ниже URL (Uniform Resource Locator – унифицированный указатель информационного ресурса. Стандартизованная строка символов, указывающая местонахождение документа в сети Интернет):
process.cgi?author=Ryan Russell
Все очень просто. Но нет никаких причин, препятствующих посылке другого URL:
process.cgi?author=Rain Forest Puppy
Так обходится предполагаемое «ограничение» HTML-формы. Более того, можно ввести URL, не запрашивая HTML-форму. Для этого следует обратиться к 80 порту Web-сервера по Telnet и сделать запрос вручную. При этом совсем не обязательно обращаться к основной форме. Не следует считать, что полученные на запрос данные – это обязательно результат обработки предыдущей HTML-формы.
Одно из заблуждений, которое автор любит опровергать, – это использование фильтра данных в клиентской части. Многие включают в HTML-формы небольшие сценарии на JavaScript или VBScript, которые контролируют заполнение всех элементов формы. Некоторые предусматривают в сценариях контроль введенных данных: введенные числовые значения действительно числовые и т. д. После такого контроля приложение работает, исходя из предположения об отсутствии ошибок в данных, введенных пользователем, и, следовательно, может сразу передать их системной функции.
На самом деле клиентская часть должна сообщать о проведенных проверках введенных данных. Если читатель не знает, как можно обойти контролирующие ввод пользователя сценарии, то задумайтесь над имеющейся даже у технически непросвещенных людей возможности отключения поддержки сценариев. Например, некоторые корпоративные межсетевые экраны отфильтровывают сценарии HTML-формы. Или злоумышленник может использовать браузеры, не поддерживающие сценарии (например, Lynx).
Следует особенно отметить, что использования параметра size HTML-формы, который описывает размер входного поля, недостаточно для предотвращения переполнения буфера. Значение параметра size клиент может установить сам, если в этом есть необходимость (или если он понимает значение этого параметра).
Если бы в протоколе HTTP придумали что-нибудь в интересах безопасности, это обязательно затронуло бы файлы cookies (небольшой фрагмент данных о предыстории обращений пользователя к WWW-серверу, автоматически создаваемый сервером на машине пользователя). Похоже, что никто еще до конца не понял, что это такое и как им правильно пользоваться. Пресса объявила их самой большой угрозой персональной безопасности в Интернет. Некоторые используют их для хранения важных данных аутентификации. Плохо, что никто из них не прав.
Механизм cookies является эффективным методом передачи данных клиентам с возвратом. Является ли это нарушением безопасности? Единственные данные, возвращаемые клиентами на сервер, – это ранее переданные им данные. Существует возможность ограничить cookies так, что клиент будет только отсылать их обратно на сервер. Предназначен cookies для обеспечения сохранения информации состояния во время многочисленных запросов, поскольку HTTP – протокол без сохранения состояния, то есть каждый запрос, выполненный индивидуальным клиентом, независимый и анонимный.
Поскольку cookies – составляющая часть HTTP, любая передаваемая c их помощью информация – это текст. Обмануть cookies не так уж и сложно. Рассмотрим обращение Telnet к 80 порту Web-сервера:GET / HTTP/1.0
User-Agent: HaveACookie/1.0
Cookie: MyCookie=SecretCookieDataТолько что был отправлен файл cookie «MyCookie» вместе с хранящимися в нем данными «SecretCookieData». Другой интересный факт о cookies: они обычно хранятся в текстовом файле клиента. Поэтому при сохранении важной информации в cookie всегда есть вероятность неавторизованного доступа к ним.
Непредвиденные данные в запросах SQL
Многие приложения и системы электронной коммерции взаимодействуют с базами данных. Небольшие базы данных могут быть встроены в приложения для настройки и структурированного хранения данных, например системный реестр Windows. Короче говоря, базы данных присутствуют везде.
Язык структурированных запросов SQL (Structured Query Language) – стандартный международный язык доступа к реляционным базам данных, используемый для передачи команд системе управления базами данных и получения от нее ответов. Можно смело сказать, что большинство коммерческих реляционных серверов баз данных совместимы с языком SQL, поскольку SQL является стандартом ANSI.
А теперь самое ужасное в SQL. Считается, что для нормальной работы приложение должно иметь доступ к базе данных. Поэтому приложение должно иметь права, необходимые для получения доступа к серверу базы данных и соответствующим ресурсам. При попытках злоумышленника изменить команды, посылаемые приложением к серверу базы данных, он воспользуется установленными правами приложения. Никакой дополнительной проверки подлинности злоумышленнику не потребуется. Он даже напрямую не взаимодействует с сервером базы данных. Можно расставить столько межсетевых экранов между сервером базы данных и сервером приложений, сколько вы можете себе позволить. Но если приложение может использовать базу данных, то у злоумышленника есть возможность получить доступ к базе данных.
Естественно, что получение доступа к базе данных не означает возможности злоумышленника сделать с сервером базы данных все, что угодно, потому что приложение может иметь ограниченный доступ к ресурсам. В результате фактический доступ атакующего к серверу базы данных и его ресурсам также будет ограничен.
Одна из самых больших угроз, вызванная включением данных пользователя в запрос SQL, заключается в передаче злоумышленником дополнительных команд, выполняемых сервером. Представьте, что простенькое приложение захочет просмотреть таблицу данных пользователя. Запрос может выглядеть примерно так:
SELECT * FROM table WHERE x=$data
В этом запросе вместо переменной $data будут подставлены данные пользователя. Затем запрос будет передан системе управления базами данных. А теперь представим, что злоумышленник подготовил следующую строку данных: