首页 > 网络安全 > XPath注入攻击及防范

XPath注入攻击及防范

2007年10月9日 发表评论 阅读评论

避免 XPath 注入的危险
–意识到风险以便更好地保护 XML 应用程序

Robi Sen (rsen@department13.com), 服务副总裁, Department13

随着简单 XML API、Web 服务和 Rich Internet Applications (RIAs) 的发展,更多组织几乎在所有方面(从配置文件到远程过程调用)都采用 XML 作为数据格式。一些人已经使用 XML 文档代替更传统的纯文本文件或关系数据库,但是与任何其他允许外部用户提交数据的应用程序或技术相似,XML 应用程序可能容易受到代码注入的攻击,尤其是 XPath 注入攻击。

简介

随着新技术的出现并得到很好的沿用,针对这些技术的威胁也随之产生并逐渐增多。SQL 盲注攻击是一种为人熟知的代码注入攻击形式,但是也有很多其他形式,有些尚未得到很好的记载和了解。最近开始出现的一种代码注入攻击是 XPath 注入攻击,它利用了 XPath 解析器的松散输入和容错特性,让心怀不满的人能够在 URL、表单或其他方法上附带恶意的 XPath 查询以获得权限信息的访问权并更改这些信息。

本文考察了通常情况下如何执行 XPath 攻击并提供了一个 Java™ 和 XML 环境中的例子。讨论了如何检测这类威胁,考察了如何减轻该威胁,最后讨论了如何应对可疑的入侵。

入门

本文主要介绍代码注入攻击的一种特殊类型:XPath 盲注。如果您不熟悉 XPath 1.0 或需要了解基础知识,请查看 W3 Schools XPath 教程(请参阅 参考资料 中的链接)。您还可以在 developerWorks 上找到大量的关于在各种语言环境中使用 XPath 的文章(请参阅 参考资料 中的链接)。本文使用的示例主要针对 XPath 1.0,但是也可用于 XPath 2.0。XPath 2.0 实际上增加了您可能遇到的问题。

本文还提供了用于处理 Java JDK 5.0 的 Java 代码示例。同时本文的概念和主题是跨平台的,如果您的应用程序使用 XPath 获取特殊的代码示例,那么您必须使用 JDK 5.0。

代码注入

一种更常见的对 Web 应用程序的攻击和威胁是某种形式的代码注入,Wikipedia 将其定义为:

……利用系统没有对其输入进行强制执行或检查的假设向计算机系统中引入(或 “注入”)代码的技术。注入代码的目的通常是绕过或修改程序的最初目标功能。如果被绕过的功能涉及系统安全,那么结果可能是灾难性的。

快速浏览任何相关 Web 站点(比如 Web Application Security Consortium 或 Security Focus,请参阅 参考资料 中的链接)都会显示很多使用某种形式的代码注入进行的攻击,从 JavaScript 到 SQL 注入再到其他形式的代码注入攻击。最近开始出现的一种威胁(最初由 Amit Klein 于 2004 年在一篇论文中概述)是 XPath 盲注攻击(请参阅 参考资料)。这种攻击的运作跟 SQL 盲注攻击几乎完全相似,与 SQL 注入攻击不同的是,几乎没什么人了解 XPath 盲注攻击或对其进行预防。与 SQL 注入攻击类似,如果使用最佳实践开发安全的应用程序,通常可以轻松地处理该威胁。

XPath 攻击

一般说来,大多数 Web 应用程序使用关系数据库存储和检索信息。例如,如果您的 Web 站点需要身份验证,那么您可能拥有一个 users 表,其中包含惟一 ID、登录名、密码,也许还有一些其他信息,比如角色。从 users 表中检索用户的 SQL 查询可能类似于清单 1。

清单 1. 从 users 表中检索用户的 SQL 查询

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. 匹配 SQL 查询的 XPath 语句

//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 之类的方法,使用 清单 3 中的 XML 文档再次执行身份验证。可能类似于清单 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;
//print first names to the console
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,如果您传入一个 login 和 password,比如 loginID = 'abc' 和 password = 'test123',则该类将返回 true(而且就本例而言,还会打印一列 first name 到控制台)。例如,如果您传入类似 ' 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

与 清单 7 中的 1=1 不同,清单 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 文档,如 Klein 的论文中提及的那样。

XPath 注入预防

因为 XPath 注入攻击与 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 “(\'|\”)”)查找字符串中的单引号和双引号并禁止它们。您也可以使用同样的方法筛选和禁止其他形式的特殊字符,比如 (“*^';&><详见原始链接:http://www.ibm.com/developerworks/cn/xml/x-xpathinjection.html

转载请注明:woyigui's blog [http://www.woyigui.cn/]
本文标题:XPath注入攻击及防范
本文地址:http://www.woyigui.cn/2007/10/09/xpath%E6%B3%A8%E5%85%A5%E6%94%BB%E5%87%BB%E5%8F%8A%E9%98%B2%E8%8C%83/

分类: 网络安全 标签:
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.
*