XPath 注入¶
ID: cs/xml/xpath-injection
Kind: path-problem
Security severity: 9.8
Severity: error
Precision: high
Tags:
- security
- external/cwe/cwe-643
Query suites:
- csharp-code-scanning.qls
- csharp-security-extended.qls
- csharp-security-and-quality.qls
如果使用字符串连接构建 XPath 表达式,并且连接的组件包含用户输入,则用户很可能能够创建恶意 XPath 表达式。
建议¶
如果必须在 XPath 表达式中包含用户输入,请预编译查询并使用变量引用来包含用户输入。
使用 System.Xml.XPath
API 时,可以通过创建 System.Xml.Xsl.XsltContext
的自定义子类型并实现 ResolveVariable(String, String)
来返回用户提供的数据来完成此操作。可以使用 XPathExpression.SetContext()
为给定的 XPathExpression
指定此自定义上下文。有关更多详细信息,请参阅参考列表中的“用户定义的函数和变量”网页。
示例¶
在第一个示例中,代码接受用户指定的用户名,并在 XPath 表达式中使用此未经验证和未经清理的值。这很容易受到用户提供特殊字符或字符串序列的攻击,这些字符或字符串序列会更改 XPath 表达式的含义以搜索不同的值。
在第二个示例中,XPath 表达式是一个硬编码字符串,它指定了一些变量,这些变量在运行时使用自定义 XsltContext
安全地替换,该上下文在 XsltArgumentList
中查找变量。
using System;
using System.Web;
using System.Xml.XPath;
public class XPathInjectionHandler : IHttpHandler
{
public void ProcessRequest(HttpContext ctx)
{
string userName = ctx.Request.QueryString["userName"];
// BAD: Use user-provided data directly in an XPath expression
string badXPathExpr = "//users/user[login/text()='" + userName + "']/home_dir/text()";
XPathExpression.Compile(badXPathExpr);
// GOOD: XPath expression uses variables to refer to parameters
string xpathExpression = "//users/user[login/text()=$username]/home_dir/text()";
XPathExpression xpath = XPathExpression.Compile(xpathExpression);
// Arguments are provided as a XsltArgumentList()
XsltArgumentList varList = new XsltArgumentList();
varList.AddParam("userName", string.Empty, userName);
// CustomContext is an application specific class, that looks up variables in the
// expression from the varList.
CustomContext context = new CustomContext(new NameTable(), varList)
xpath.SetContext(context);
}
}
参考¶
OWASP:测试 XPath 注入。
OWASP:XPath 注入。
MSDN:用户定义的函数和变量。
常见弱点枚举:CWE-643。