本节书摘来异步社区《java编码指南:编写安全可靠程序的75条建议》一书中的第1章,第1.8节,作者:【美】fred long(弗雷德•朗), dhruv mohindra(德鲁•莫欣达), robert c.seacord(罗伯特 c.西科德), dean f.sutherland(迪恩 f.萨瑟兰), david svoboda(大卫•斯沃博达),更多章节内容可以访问云栖社区“异步社区”公众号查看。
可扩展标记语言(extensible markup language,xml)可用于以类似于关系数据库的方式来存储数据。xml文档中的数据通常是用xpath来检索。当给xpath检索例程提供的数据没有做合适的无害化处理时,就有可能会导致xpath注入(xpath injection)攻击。这种攻击类似于sql注入或xml注入(参见《the cert® oracle® secure coding standard for java™》[long 2012]的“ids00-j. sanitize untrusted data passed across a trust boundary”。攻击者可以在查询用的数据字段中输入有效的sql构造或xml构造。典型的攻击是,让条件查询字段解析为一个永真式,这样就会导致攻击者访问到未经授权的信息。
该指南是指南7的一个具体示例。
xml路径注入示例
先来看看下面的xml模式。
//users/user[username/text()='&login&' and
password/text()='&password&' ]<code>`</code>
如果攻击者知道utah是一个有效的用户名,他可以指定一个下面这样的输入:
//users/user[username/text()='utah' or '1'='1'
and password/text()='xxxx']<code>`</code>
因为'1'='1'自动为真,所以密码永远也不会被检查。因此,攻击者在不知道用户utah的密码的情况下被不适当地验证成了该用户。
下面的违规代码示例从用户输入中读取用户名和密码,并使用它们来构建查询字符串,将密码以字符数组的形式传递,然后对其进行散列加密。这个示例容易受到上面提到的那种方式的攻击。如果将上面描述的攻击字符串传递给evaluate()方法,这个方法调用会返回xml文件中的相应节点,这会导致dologin()方法返回true,并绕过所有授权。
输入文件:login.xq
declare variable $username as xs:string external;
declare variable $password as xs:string external;
//users/user[@username=$username and @password=$password]<code>`</code>
下面的合规解决方案从一个文本文件中读取所需的特定格式的查询语句,然后将用户名和密码的值插入一个映射中。xquery库构造了这些来自用户输入的xml查询。
根据owasp [owasp 2013]: