当前位置: 首页 > 工具软件 > XQuery > 使用案例 >

应用安全系列之十七:xQuery注入

湛宏旷
2023-12-01

本系列文章主旨在于介绍一些漏洞类型产生的基本原理,探索最基础的解决问题的措施。

关于xQuery标准的详细信息可以参考http://www.w3.org/TR/xquery/, 这里只做简单介绍。

XQuery语言是用于查询存储在XML数据库的数据的语言,它可以看做是XPath语言的一个超集。主要用到的XQuery的功能包括:

  •  构建XQL查询
  •  从XML数据库获取信息给web服务或者应用
  • 从XML数据库中年获取XML格式的报告
  • 把XML数据转换成XHTML
  • 快速遍历XML树
  • 根据过滤器过滤得到查询的结果

还是用员工信息的例子,employee.xml的内容如下:


<?xml version="1.0" encoding="utf-8"?>
<Employees>
	<Employee ID="1">
        <FirstName>Ade</FirstName>
        <LastName>Li</LastName>
        <UserName>Adel</UserName>
        <Password>Test@123</Password>
        <Type>Admin</Type>
    </Employee>
    <Employee ID="2">
        <FirstName>Taylor</FirstName>
        <LastName>Kuang</LastName>
        <UserName>TaylorK</UserName>
        <Password>TaylorK@2021</Password>
        <Type>User</Type>
    </Employee>
</Employees>

假设组装XQuery的查询的代码如下:

String query="for $Employee in doc(Employee.xml)/Employees/Employee[UserName='" +UserName +"'] return $Employee";

查询“Ade”的XQuery查询如下:doc("Employee.xml")/Employees/Employee[UserName="Ade"],返回的结果如下:

<Employee ID="2">
        <FirstName>Taylor</FirstName>
        <LastName>Kuang</LastName>
        <UserName>TaylorK</UserName>
        <Password>TaylorK@2021</Password>
        <Type>User</Type>
    </Employee>

和SQL注入类似,如果用户对于UserName输入的内容修改为 " or ""=",就会导致查询语句修改为:doc("Employee.xml")/Employees/Employee[UserName="" or ""=""],就会查询获取所有用户的信息。或者简单一点用户直接输入 *,也可以达到一样的效果。

由上例可知,XQuery注入主要是在构建XQuery查询的时候,接收了不可信的数据而且没有做输入验证,并且用于动态构建查询语句造成的。根据XQuery查询结果使用的不同环境造成的影响也不同,主要有:

  1. 泄露系统内部的数据的信息
  2. 如果用于鉴权,可能会出现越权
  3. 也可能会导致XML数据库数据被篡改, 可以设置符合条件的数据被update或者delete
  4. 执行恶意代码 

危害这么严重改如何预防呢?

  1. 如果在设计上避免使用不可信数据构建XQuery是最好的。
  2. 使用最小权限原则,以防数据被篡改。
  3. 输入验证,严格的输入验证对于预防注入问题来说,总是必要的。
  4. XQuery的一些扩展模块可以用于执行命令,建议尽量避免启用这些扩展模块。
  5. 使用参数化查询,和SQL的参数化查询PrepareStatement类似,示例代码如下:
  6. DocumentBuilderFactory docFac = DocumentBuilderFactory.newInstance();
    docFac.setNamespaceAware(true);
    DocumentBUilder builder = docFac.newDocumentBuilder();
    Document doc = builder.parse("Employee.xml");
    
    String queryName = request.getParameter("UserName");
    XQuery  query = new XQueryFactory().createXQuery(new File("queryEmployee.xq"));
    Map  queryFieldValue = new HashMap();
    queryFieldValue.put("UserName", queryName);
    NodeList nodes = query.execute(doc, null, queryFieldValue).toNodes();

  7. 有时做输入验证会失效,例如, 人名字(O'Neal)中可能会存在单引号,这是需要转义特殊字符,需要转义的字符和转义方法如下:

               

        说明
&&amp;有时会被用于引用预定义的实体
 '&apos;字符串开始结束标志
"&quot字符串开始结束标志

如果有不妥之处,希望可以留言指出。谢谢!

参考:

The Web Application Security Consortium / XQuery Injection

Balisage: XQuery Injection

XQuery Injection

CAPEC - CAPEC-84: XQuery Injection (Version 3.9)

 类似资料: