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

Узнайте о рисках, чтобы лучше защитить XML-приложения

С распространением простых 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 ''='']

Эта строка логически приведет к запросу, всегда возвращающему 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] стратегии защищенности приложения, основываясь на передовом опыте разработки защищенных приложений (см. отличный список от Apache для Web-сервисов, ссылка на который приведена в разделе "Ресурсы").
  • Тестируйте приложение на известные угрозы перед его выпуском. В статье "Fuzz Testing", ссылка на которую приведена в разделе "Ресурсы", показано, как это делается.

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

В отличие от большинства приложений баз данных, 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-внедрением, но и от остальных форм атак.

Ресурсы

Научиться

  • Оригинал статьи "Avoid the dangers of XPath injection" (EN).
  • The Java XPath API (EN) (Элиот Расти Гарольд (Elliotte Rusty Harold), developerWorks, июль 2006): информация о запросе XML из Java-программ.(EN)
  • Учебное руководство W3 Schools XPath (EN): пример XPath 1.0.(EN)
  • Начало работы с XPath 2.0 (EN) (Бенуа Марчал (Benoît Marchal), developerWorks, май 2006): информация о том, как просто писать сложные запросы с новой моделью данных.(EN)
  • Web Application Security Consortium: Web-сайт международной группы экспертов, практиков и представителей организаций, разрабатывающих системы с открытыми исходными кодами и основывающихся на передовых стандартах защиты приложений для World Wide Web.(EN)
  • Security Focus: ресурсы для экспертов по защите приложений.(EN)
  • Скрытое XPath-внедрение: описание атаки с XPath-внедрением от Амита Клэйна (Amit Klein).(EN)
  • Apache: отличная статья по передовому опыту защиты Web-сервисов.
  • Fuzz testing (EN) (Элиот Гарольд (Elliotte Harold), developerWorks, сентябрь 2006): что может произойти при преднамеренном внедрении случайных некорректных данных в приложение, приводящем к аварийной ситуации, и как использовать защищающие методики кодирования.(EN)
  • Раздел developerWorks XML: сотни дополнительных ресурсов по XML.
  • Сертификация IBM XML: информация о том, как стать специалистом IBM-Certified Developer по XML и смежным технологиям.(EN)
  • Техническая библиотека по XML: в разделе XML на developerWorks размещено множество технических статей, советов, учебных руководств, стандартов и книг IBM Redbooks.
  • Технические события и Web-трансляции developerWorks: следите за новинками технологии.(EN)

Получить продукты и технологии

Обсудить

Комментарии

developerWorks: Войти

Обязательные поля отмечены звездочкой (*).


Нужен IBM ID?
Забыли Ваш IBM ID?


Забыли Ваш пароль?
Изменить пароль

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


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

Вся введенная информация защищена.

Выберите имя, которое будет отображаться на экране



При первом входе в developerWorks для Вас будет создан профиль и Вам нужно будет выбрать Отображаемое имя. Оно будет выводиться рядом с контентом, опубликованным Вами в developerWorks.

Отображаемое имя должно иметь длину от 3 символов до 31 символа. Ваше Имя в системе должно быть уникальным. В качестве имени по соображениям приватности нельзя использовать контактный e-mail.

Обязательные поля отмечены звездочкой (*).

(Отображаемое имя должно иметь длину от 3 символов до 31 символа.)

Нажимая Отправить, Вы принимаете Условия использования developerWorks.

 


Вся введенная информация защищена.


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=XML, Технология Java, SOA и web-сервисы
ArticleID=279687
ArticleTitle=Устранение опасности XPath-внедрения
publish-date=01022008