Продолжается подписка на наши издания! Вы не забыли подписаться?

Устранение опасности XPath-внедрения

Автор: Роби Сен
Department13
Опубликовано: 23.04.2008,
http://www.ibm.com/developerworks/ru/library/x-xpathinjection

С распространением простых XML API, Web-сервисов и полнофункциональных Интернет-приложений (Rich Internet Application – RIA) все больше организаций использует XML как формат данных для всего - от конфигурационных файлов до вызовов удаленных процедур. Некоторые даже используют XML-документы вместо традиционных обычных (flat) файлов или реляционных баз данных, но, как и любые другие приложения или технологии, позволяющие ввод пользователем данных извне, XML-приложения могут быть восприимчивы к атакам в виде внедрения кода, в частности, атакам XPath-внедрения.

Введение

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

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

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

Предметом обсуждения данной статьи является специфический тип атаки с внедрением кода Blind XPath-внедрение. Если вы не знакомы с XPath 1.0 или нуждаетесь в примере, обратитесь к учебному руководству W3 Schools XPath (ссылка приведена в разделе "Ресурсы"). Также вы найдете много статей по работе с XPath на различных языках программирования на developerWorks (ссылки приведены в разделе "Ресурсы"). В данной статье будут использованы примеры для 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

<?xml version="1.0" encoding="UTF-8"?> 
<users> 
      <user>  
          <firstname>Ben</firstname>
          <lastname>Elmore</lastname> 
          <loginID>abc</loginID> 
          <password>test123</password> 
      </user> 
      <user>  
          <firstname>Shlomy</firstname>
          <lastname>Gantz</lastname>
          <loginID>xyz</loginID> 
          <password>123test</password> 
      </user> 
      <user>  
          <firstname>Jeghis</firstname>
          <lastname>Katz</lastname>
          <loginID>mrj</loginID> 
          <password>jk2468</password> 
      </user> 
      <user>  
          <firstname>Darien</firstname>
          <lastname>Heap</lastname>
          <loginID>drano</loginID> 
          <password>2mne8s</password> 
      </user> 
 </users> 

Для 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 ''='']

This will logically result in a query that always returns true and will always allow the attacker to gain access.

Это логично приведет к запросу, всегда возвращающему 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-внедрения. Не удивительно, что большинство этих предупредительных методов можно и должно использовать для предотвращения других типичных атак с внедрением кода.

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

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

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

В отличие от большинства приложений баз данных, 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 "(\'|\")"), чтобы найти в строках одиночные и двойные кавычки и запретить их. Такой же подход можно применить для фильтрации и запрета других форм специальных символов (например, ("*^';&><</)), которые могут быть использованы для различных атак с внедрением кода. Этот подход может быть очень хорош для некоторых приложений, которые, возможно, используют основанные на REST или SOAP XML-сервисы, но в других случаях он может быть не возможен. Как всегда наилучшим подходом является разумное проектирование, начиная с первоначального дизайна и до реализации приложения.

А что, если?

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

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

Резюме

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

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

Ресурсы


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

Copyright © 1994-2016 ООО "К-Пресс"