Календарь на Май 2024 года: calendar2008.ru/2024/may/
Навигация
Главная »  Xml 

Устранение опасности XPath-внедрения (исходники)


Источник: IBM developerWorks Россия
Роби Сен, независимый автор, Department13

Введение

По мере появления и становления новых технологий возрастают также угрозы этим технологиям. Скрытые атаки SQL-внедрения являются хорошо известными и распознаваемыми формами атак внедрения кода, но имеется много других форм, которые не настолько хорошо документированы или распознаваемы. Новой атакой внедрения кода является атака XPath-внедрения, использующая преимущества свободной типизации (loose typing) и снисходительность синтаксических анализаторов XPath, позволяющих злоумышленникам использовать в своих интересах некорректные XPath-запросы в URL, формах или других методах для получения доступа к привилегированной информации и изменения ее.

В данной статье рассказывается, как осуществляются XPath-атаки, а также предоставляется пример для сред Java™ и XML. Кроме того, обсуждается вопрос, как обнаружить эти угрозы, что можно сделать для уменьшения опасности и, наконец, что предпринять в ответ на подозрительное проникновение.

Начало работы

Предметом обсуждения данной статьи является специфический тип атаки с внедрением кода Blind XPath-внедрение. В данной статье будут использованы примеры для XPath 1.0, но они работают и для XPath 2.0. XPath 2.0, фактически, расширяет круг возможных проблем, с которыми вы можете столкнуться.

С данной статьей предоставляется также пример Java-кода, созданный для работы с Java JDK 5.0. Хотя концепции и темы, обсуждаемые в данной статье, являются кросс-платформенными, если в приложении для получения конкретного примера кода применяется XPath, необходимо использовать JDK 5.0.

Внедрение кода

Одной из наиболее типичных атак или угроз для Web-приложений является определенного рода внедрение кода, которое Википедия определяет как:

... технический прием внедрения (или "инъекции") кода в компьютерную программу или систему путем использования нереализованных и не проверяемых предположений, которые система должна делать при вводе данных. Целью внедрения кода обычно является обход или изменение оригинальной функциональности программы. Когда такой функциональностью является система защиты, последствия могут быть роковыми.
Внимательное ознакомление с такими Web-сайтами как Web Application Security Consortium или Security Focus поможет получить информацию о разнообразных атаках, использующих форму внедрения кода какого-либо рода - от JavaScript до SQL-внедрения и других форм атак. Одной из новых угроз (впервые упомянута Амитом Клейном (Amit Klein) в статье 2004 года) является атака скрытого XPath-внедрения. Она выполняется почти так же, как и атака скрытого SQL-внедрения, но, в отличие от нее, не многие люди знают об атаках XPath-внедрения или предпринимают против них какие-то меры. Аналогично атаке SQL-внедрения, чаще всего можно легко предотвратить эту угрозу, если следовать передовому опыту разработки защищенных приложений.

Атака XPath

Обычно большинство Web-приложений для хранения данных и извлечения информации использует реляционные базы. Если, положим, у вас есть Web-сайт, требующий аутентификации, вероятно, существует таблица users с уникальным ID, именем входа в систему, паролем, и (возможно) информацией какого либо другого рода, например, ролью. SQL-запрос для извлечения информации о пользователе из таблицы users может выглядеть так, как показано в листинге 1.

Листинг 1. SQL-запрос для извлечения информации о пользователе из таблицы users
Select * from users where loginID='foo' and password='bar' 

В данном запросе пользователь должен ввести loginID и password. Если взломщик введет для поля loginID: ' or 1=1 и для поля password: ' or 1=1, сформированный запрос будет выглядеть примерно так, как показано в листинге 2.

Листинг 2. Запрос, сформированный взломщиком
 Select * from users where loginID = '' or 1=1 and password=' ' or 1=1 

Этот запрос всегда возвращает положительный результат, поэтому взломщик войдет в систему. XPath-внедрение работает примерно таким же способом. Предположим, что вместо таблицы users у вас есть XML-файл, содержащий информацию о пользователе и выглядящий так, как показано в листинге 3.

Листинг 3. user.xml
    Ben Elmore abc test123   Shlomy Gantz xyz 123test   Jeghis Katz mrj jk2468   Darien Heap drano 2mne8s   

Для XPath аналогичное SQL-запросу выражение приведено в листинге 4.

Листинг 4. XPath-выражение, соответствующее SQL-запросу
 //users/user[loginID/text()='abc' and password/text()='test123'] 

Выполняя подобную атаку (обход аутентификации), можно поступить так, как в листинге 5.

Листинг 5. Обход аутентификации
 //users/user[LoginID/text()='' or 1=1  and password/text()='' or 1=1] 

Возможно, в вашем Java-приложении есть метод (например, doLogin), выполняющий аутентификацию, опять же, с использованием XML-документа (листинг 3). Он может выглядеть так, как показано в листинге 6.

Листинг 6. XPathInjection.java
 import java.io.IOException; import org.w3c.dom.*; import org.xml.sax.SAXException; import javax.xml.parsers.*; import javax.xml.xpath.*;  public class XpathInjectionExample {     public boolean doLogin(String loginID, String password) throws ParserConfigurationException, SAXException,IOException, XPathExpressionException {  DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance(); domFactory.setNamespaceAware(true); DocumentBuilder builder = domFactory.newDocumentBuilder(); Document doc = builder.parse("users.xml");  XPathFactory factory = XPathFactory.newInstance(); XPath xpath = factory.newXPath(); XPathExpression expr = xpath.compile("//users/user[loginID/text()='"+loginID+"' and password/text()='"+password+"' ]/firstname/text()"); Object result = expr.evaluate(doc, XPathConstants.NODESET); NodeList nodes = (NodeList) result; //вывести фамилию на консоль for (int i = 0; i < nodes.getLength(); i++) { System.out.println(nodes.item(i).getNodeValue());}                       if (nodes.getLength() >= 1) { return true;} else {return false;} } } 

При передаче для листинга 6 имени и пароля в виде loginID = 'abc' и password = 'test123', класс возвратит значение true (в нашем примере список фамилий, выводимых на консоль). Если, например, вы передадите значения ' or 1=1 or ''=', вам всегда возвратится значение true, поскольку XPath закончит поиск строки, показанной в листинге 7.

Листинг 7. Строка
 //users/user[loginID/text()='' or 1=1 or ''='' and password/text()='' or 1=1 or ''=''] 

Эта строка логически приведет к запросу, всегда возвращающему true, т.е. взломщик получит постоянный доступ.

Еще одной, даже более вероятной и, возможно, более неприятной атакой в XPath является способность взломщиков использовать XPath для управления XML-документами в приложении "на лету".

Извлечение структуры XML-документа

Запрос, использовавшийся для обхода аутентификации, может также использоваться для извлечения информации об XML-документе. Допустим, взломщик делает предположение о том, что имя первого подчиненного узла в XML-документе равно loginID, и хочет удостовериться в этом. Он вводит строку, приведенную в листинге 8.

Листинг 8. Строка, вводимая взломщиком
 abc' or name(//users/LoginID[1]) = 'LoginID' or 'a'='b 

Вместо 1=1 из листинга 7 выражение в листинге 8 проверяет, равно ли имя первого подчиненного узла loginID. Сформированный запрос приведен в листинге 9.

Листинг 9. Запрос
 String(//users[LoginID/text()='abc' or name(//users/LoginID[1]) = 'LoginID' or 'a=b' and password/text()='']) 

Путем проб и ошибок взломщик может проверить различные дочерние узлы XML-документа и собрать информацию, наблюдая за результатами XPath-выражения при успешной аутентификации. Затем, в принципе, взломщик может написать простой сценарий, передающий разные XPath-внедрения и извлекающий XML-документ из системы, как упоминалось в статье Клейна.

Предотвращение XPath-внедрения

Поскольку XPath-внедрение во многом аналогично SQL-внедрению, от него можно защититься методами, похожими на те, которые используются для предотвращения атак SQL-внедрения. Не удивительно, что большинство этих предупредительных методов можно и должно использовать для предотвращения других типичных атак с внедрением кода.

Проверка корректности

Независимо от приложения, среды или языка необходимо следовать следующим практическим правилам:

  • Предполагайте, что все вводимые данные сомнительны.
  • Проверяйте не только тип вводимых данных, но также их формат, длину, диапазон и содержимое (например, такое простое регулярное выражение как if (/^"*^';&<>()/) должно находить большинство подозрительных специальных символов).
  • Проверяйте данные как на стороне клиента, так и на стороне сервера, поскольку проверку на стороне клиента чрезвычайно легко перехитрить.
  • Следуйте последовательной [missing word] стратегии защищенности приложения, основываясь на передовом опыте разработки защищенных приложений.
  • Тестируйте приложение на известные угрозы перед его выпуском.

Параметризация

В отличие от большинства приложений баз данных, XPath не поддерживает концепцию параметризации запросов, но вы можете сымитировать эту концепцию, используя другие API, например XQuery. Вместо формирования выражений в виде строк, передаваемых затем в синтаксический анализатор XPath для динамического выполнения во время исполнения (как показано в листинге 10), можно параметризировать запрос, создав внешний файл, хранящий его (см. листинг 11).

Листинг 10. Строки, передаваемые в синтаксический анализатор XPath
 "//users/user[LoginID/text()=' " + loginID+ " ' and password/text()=' "+ password +" ']" 

В листинге 11 запрос параметризирован путем создания внешнего файла, хранящего запрос.

Листинг 11. dologin.xq
 declare variable $loginID as xs:string external; declare variable $password as xs:string external;//users/user[@loginID= $loginID and @password=$password] 

Затем можно выполнить аналогичные листингу 11 действия путем небольшой модификации (листинг 12).

Листинг 12. XQuery-снипет
 Document doc = new Builder().build("users.xml"); XQuery xquery = new XQueryFactory().createXQuery(new File(" dologin.xq")); Map vars = new HashMap(); vars.put("loginid", "abc"); vars.put("password", "test123"); Nodes results = xquery.execute(doc, null, vars).toNodes(); for (int i=0; i < results.size(); i++) { System.out.println(results.get(i).toXML()); } 

Это предохранит важные явно заданные переменные $loginID и $password от обработки как вычисляемых выражений во время выполнения. То есть логика программы и данные разделены; к сожалению, параметризация запроса не входит в XPath, но она свободно доступна в синтаксических анализаторах с открытым исходным кодом, например, SAXON. Некоторые другие синтаксические анализаторы реализуют такого рода функциональность и могут быть хорошим способом защиты против XPath-внедрения.

Проверка данных на Web-сервере

Для защиты против XPath-внедрения и других форм внедрения кода необходимо проверять все данные, передаваемые от Web-сервера к службам системы хранения данных. Например, с Apache можно использовать фильтр Mod_Security (например, SecFilterSelective THE_REQUEST "(\'/\")"), чтобы найти в строках одиночные и двойные кавычки и запретить их. Такой же подход можно применить для фильтрации и запрета других форм специальных символов (например, ("*^';&><

А что, если?

В своем большинстве организации действительно задумываются об обнаружении угроз и их предотвращении, но дело редко доходит до реализации. Только тогда, когда их системы взламываются, они приглашают квалифицированных специалистов для совместного планирования мероприятий по защите. Необходимо всегда предполагать наихудший сценарий и соответственно планировать работу.

Все в значительной степени зависит от конкретной организации и типа взламываемой системы, но обычно наилучшее, что можно сделать - перевести систему в режим автономной работы (offline) и подождать, когда профессиональный инженер по безопасности проанализирует ситуацию. Иногда люди сразу же отключают систему и восстанавливают дисковые накопители из образов, но это скрывает следы преступления, так же как и возможную информацию о других нарушениях, выполненных взломщиком в данной системе. По возможности всегда старайтесь сохранить состояние системы для анализа экспертом.

Резюме

Большинство приложений, использующих XML, не будет уязвимо для атак с XPath-внедрением, а XML-приложения не должны считаться небезопасными только из-за обнаружения какой-то конкретной уязвимости. В то же время, широкое распространение новых платформ (например, Ajax, RIA-платформы FLEX или Open Laszlo), а также интеграция XML-сервисов от таких организаций как Google (которые интенсивно используют XML для всего - от обмена данными с серверами хранения данных до персистенции), вынуждает разработчиков учитывать угрозы и риски, создаваемые подобными методами работы.

К счастью, в то время как данные конкретные угрозы являются новыми, проблемы и принципы их решения - нет. Следование передовому опыту поможет защититься не только от атак с XPath-внедрением, но и от остальных форм атак.



 

 Преобразование XML в JSON на PHP (исходники).
 Web-сервисы Java, часть 3: Связывание данных в Axis2 (исходники).
 Не повторяйте DAO!.
 Организация контента с помощью категорий Atom (исходники).
 XML и Java: Возвращение к основам (исходники).


Главная »  Xml 

© 2024 Team.Furia.Ru.
Частичное копирование материалов разрешено.