Skip to content

XPath Injection Prevention Cheat Sheet / XPath注入防护技巧清单

Introduction / 介绍

XPath selects data from XML documents. XPath injection occurs when external input becomes part of an expression's syntax, allowing it to change the query's meaning. Prevent it by keeping expressions under application control and passing external values through variable binding.

XPath从XML文档中选择数据。XPath注入发生在外部输入成为表达式语法的一部分时,允许它改变查询的含义。通过保持表达式在应用控制之下,并通过变量绑定传递外部值来预防它。

Bind Values to Fixed Expressions / 将值绑定到固定表达式

Use an XPath API that supports variables. Write the expression in application code and supply external values separately. Do not concatenate or interpolate input into the expression, even if you compile it afterward: compilation alone does not separate data from query syntax.

使用支持变量的XPath API。在应用代码中编写表达式,并单独提供外部值。不要将输入连接或插值到表达式中,即使之后编译它:仅编译本身并不能将数据与查询语法分开。

For example, Python's lxml xpath() method accepts variables as keyword arguments. This illustrative lookup assumes xml_document is an already parsed lxml document and requested_id is an external string:

例如,Python的lxml xpath()方法接受变量作为关键字参数。此示例查找假设xml_document是一个已解析的lxml文档,而requested_id是一个外部字符串:

books = xml_document.xpath(
    "/catalog/book[@id=$book_id]",
    book_id=requested_id,
)

The expression stays fixed; requested_id supplies only the value of $book_id. The application must separately authorize access to the selected books.

表达式保持固定;requested_id只提供$book_id的值。应用必须单独授权访问所选书籍。

For Java, use the resolver pattern shown in the Java example below. Check the documentation for your particular API: accepting an XPath string or compiling an expression does not by itself mean the API provides variable binding.

对于Java,使用下面Java示例中显示的解析器模式。检查您特定API的文档:接受XPath字符串或编译表达式本身并不意味着API提供变量绑定。

If the API cannot bind values, prefer one that can. Where practical, use a fixed expression to retrieve an authorized set of records and compare values in application code. Do not substitute ad hoc quote replacement for variable binding.

如果API无法绑定值,则优先选择可以绑定的API。在可行的情况下,使用固定表达式检索授权的记录集,并在应用代码中比较值。不要用即兴的引号替换来代替变量绑定。

Keep Query Structure Under Application Control / 将查询结构控制在应用程序控制之下

XPath variables represent values) (XPath 变量表示值); they do not substitute expression fragments. When a user chooses a query mode, map that choice to a complete, fixed expression defined by the application. Reject unknown choices and bind any external data values separately.

For example, a catalog application can map the choices books and magazines to the fixed paths /catalog/book and /catalog/magazine. Do not insert the selected choice directly into a path or accept user-supplied predicates, operators, or function calls.

例如,一个目录应用程序可以将选择 books 和 magazines 映射到固定路径 /catalog/book 和 /catalog/magazine。不要直接将所选选项插入路径中或接受用户提供的谓词、运算符或函数调用。

Validate values against the application's expected types, lengths, and business rules, following the Input Validation Cheat Sheet. Validation complements binding; it does not make dynamically constructed XPath safe by itself.

根据输入验证作弊表验证值与应用程序期望的类型、长度和业务规则,验证补充绑定;它本身并不能通过动态构建 XPath 来使其安全。

Limit Exposure and Review Usage / 限制暴露并审查使用

Keep these controls separate from the binding mechanism:

将这些控制与绑定机制分开:

  • Authorization: Check the caller's permission to access each requested resource. A fixed query, narrow path, or bound identifier does not establish permission. Follow the Authorization Cheat Sheet and the principle of least privilege to limit the data an operation can access and return.
    中文:授权:检查调用者访问每个请求资源的权限。固定的查询、狭窄的路径或限制的标识符并不能确立权限。遵循授权速查表和最小权限原则,以限制操作可以访问和返回的数据。
  • Error handling: Keep XPath expressions, XML contents, and stack traces out of client-facing error messages. Follow the Error Handling Cheat Sheet. Generic errors reduce disclosure; they do not prevent injection.
    中文:错误处理: 将 XPath 表达式、XML 内容和堆栈跟踪从面向客户端的错误消息中排除。遵循错误处理作弊表。通用错误减少了披露;它们并不能防止注入。
  • XML parsing: Configure the parser according to the XML External Entity Prevention Cheat Sheet. Parser hardening addresses XML parser risks, not unsafe XPath construction; binding values does not harden the parser.
    中文:XML 解析: 根据XML外部实体预防作弊表[XML_External_Entity_Prevention_Cheat_Sheet.md]配置解析器。解析器加固解决XML解析器风险,而不是不安全的 XPath 构造;绑定值并不能加固解析器。

During code review, locate calls that evaluate or compile XPath. Trace each expression back to application-controlled text and verify that external values reach it only through variable binding. For fixed query mappings, verify that unknown choices are rejected. Include correctness checks for ordinary valid values, absent records, and access to resources outside the caller's permissions.

代码审查期间,定位评估或编译 XPath 的调用。将每个表达式回溯到应用程序控制的文本,并验证外部值是否仅通过变量绑定到达。对于固定查询映射,验证未知选项是否被拒绝。包括对普通有效值、不存在记录和调用者权限之外的资源访问的正确性检查。

For security assessment guidance, see the Web Security Testing Guide's XPath injection chapter.

有关安全评估指南,请参阅 OWASP Web 安全测试指南的 XPath 注入章节。

Other Examples / 其他示例

Java

Bind the untrusted value with an XPathVariableResolver (OK):

使用 XPathVariableResolver(OK)绑定不受信任的值:

XPath xpath = XPathFactory.newInstance().newXPath();
xpath.setXPathVariableResolver(name -> name.equals(new QName("bookId")) ? bookId : null);
XPathExpression xPathExpression = xpath.compile("//book[@id=$bookId]");

Example of vulnerable code building a XPath query using dynamic input:

使用动态输入构建 XPath 查询的易受攻击代码示例:

// BAD
XPathExpression xPathExpression = xpath.compile("//book[@id=" + bookId + "]");

References / 参考