Защита от XPath-инъекций
XPath это язык запросов, предназначенный для обмена данными в XML-документах. Другими словами данные можно хранить в XML документах вместо баз данных, только в данной структуре нет привычных таблиц. Вместо таблиц в XML документах используются nodes. Так же как и SQL, XPath уязвим к инъекциям произвольного кода, которые могут нарушить синтаксис операции.
Использовать XPath вместо баз данных рекомендуется для разгрузки SQL-сервера. Например, многие XML приложения используют дампы баз данных. В связи с этим возникает опасность использования хранения таких данных.
Дело в том, что XPath является простым языком, относительно SQL. Поэтому подобрать инъекцию к запросу в XPath проще. Также некоторой уязвимостью является то, что в XPath можно получить любой объект из запроса, а иногда даже всю базу.
Следующий XPath запрос выбирает пользователя с заданным паролем из БД:
string(//user[name/text()='user1' and password/text()='1234']/account/text())
Таким образом, если переменные имени и пароля получаются от пользователя, возникает риск нарушения логики запроса и выполнения произвольных операций.
XmlDocument XmlDoc = new XmlDocument(); XmlDoc.Load("..."); XPathNavigator nav = XmlDoc.CreateNavigator(); XPathExpression expr = nav.Compile("string(//user[name/text()='"+TextBox1.Text+"' and password/text()='"+TextBox2.Text+ "']/account/text())"); String account=Convert.ToString(nav.Evaluate(expr)); if (account=="") { // name+password pair is not found in the XML document – // login failed. } else { // account found -> Login succeeded. // Proceed into the application. }
Данный код выбирает номер кредитной карты пользователя из базы даных. Если злоумышленник введет:
' or 1=1 or ''='
То данный запрос вернет первый номер кредитной карты, которая вероятно окажеться пользователя admin.
Данный пример наглядно демонстрирует всю опасность XPath инъекций. Защититься от них также просто как и от обычных SQL-инъекций. Достаточно проверять все входящие данные от пользователей на предмет их соответствия выражению. Например, если это номер кредитки, то достаточно будет только цифр. Используя регулярные выражения и параметризованные запросы, можно полностью избежать подобных уязвимостей. Данные методы описаны в предыдущих статьях о защите баз данных, так что сейчас не имеет смысла их переписывать.