本文重点讲解xpath的语法。因为真他妈的难搞。
首先,xpath分1.0和2.0 ,2.0的方法很多,各种牛逼的方法 很便捷,但是他妈逼的pmd和sonar部分其他的xpath规则只能支持1.0的。如果你用2.0语法 经常会看到以下的报错
ERROR] Failed to execute goal org.sonarsource.scanner.maven:sonar-maven-plugin:3.7.0.1746:sonar (default-cli) on project pig: Unable to analyse file /Users/xsser/Downloads/xxxmasaike/pom.xml: Can't compile XPath expression "//groupId[contains(text(),'com.alibaba')] [ERROR] [../artifactId[contains(text(),'fastjson')]] [ERROR] [../version[contains('1.2.4')]]" for rule xml:______fastjson: javax.xml.transform.TransformerException: com.sun.org.apache.xpath.internal.functions.FuncContains仅允许使用2参数 [ERROR] -> [Help 1] |
我觉得还是pmd引用的这个包太老了,改个支持2.0的可能就好了?我没试过,应该可以啊吧。。谁去试试
1.0的语法叫xquery,2.0 叫做xpath.
比如
<?xml version="1.0" encoding="ISO-8859-1"?>
<bookstore>
<book category="COOKING"> <title>Everyday Italian</title> <author>Giada De Laurentiis</author> <year>2005</year> <price>30.00</price> </book>
<book category="CHILDREN"> <title>Harry Potter</title> <author>J K. Rowling</author> <year>2005</year> <price>29.99</price> </book>
<book category="WEB"> <title>XQuery Kick Start</title> <author>James McGovern</author> <author>Per Bothner</author> <author>Kurt Cagle</author> <author>James Linn</author> <author>Vaidyanathan Nagarajan</author> <year>2003</year> <price>49.99</price> </book>
<book category="WEB"> <title>Learning XML</title> <author>Erik T. Ray</author> <year>2003</year> <price>39.95</price> </book>
</bookstore> |
我们要选取选取 bookstore 元素下的所有 book 元素,并且所选取的 book 元素下的 price 元素的值必须小于 30:
那么我们的xquery应该是:
doc("books.xml")/bookstore/book[price<30]
然儿这个,在xpath规则里这么写完全没鸟用,也不知道为啥。
先分享下教程地址
Xquery的教程https://www.runoob.com/xquery/xquery-example.html
Xpath的教程 https://www.runoob.com/xpath/xpath-tutorial.html
分享几个我写的xpath2.0的实例
危险的fastjson检测1.2.4
1.//groupId[contains(text(),'com.alibaba')][../artifactId[contains(text(),'fastjson')]] [../version[contains(text(),'1.2.4')]] ---------------------------------------------------------------------- 2.//groupId[contains(text(),'com.alibaba')][../artifactId[contains(text(),'fastjson')]] [../version[contains(text(),'1.1.')]] ---------------------------------------------------------------------- 3.//groupId[contains(text(),'com.alibaba')][../artifactId[contains(text(),'fastjson')]] [../version[contains(text(),'1.0.')]] |
我们拿第一条举例
//表示任意位置开头,//groupId就是任意位置开头的groupId元素
假设我们要检测以下这个pom.xml
<dependencyManagement> <dependencies> <!--fastjson 版本--> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.48</version> </dependency> <!--web 模块--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>${spring-boot.version}</version> <exclusions> <!--排除tomcat依赖--> <exclusion> <artifactId>spring-boot-starter-tomcat</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> </dependency> </dependencies> </dependencyManagement> |
如果我们的xpath是
//groupId
那么xml里有3个会被选中
如果我们要选择fastjson这个,我们就要编写规则为:
//groupId[text()=’com.alibaba’]
然后就可以扫描到这个了,但是这样只是检测到了引用了com.alibaba 还不够细。规则里的text()方法是返回groupId这个元素的文本内容,[]表示约束性的条件,任何形容词都在这个[]填写,而且可以接多个这样的条件表达式
常见的几个方法,contains(),text(),number()
//groupId[contains(text(),'com.alibaba')][../artifactId[contains(text(),'fastjson')]][../version[contains(text(),'1.2.4')]]
解释下这个规则的意思,首先//groupId就是定位到任意的groupId元素,然后第一个中扩号表示这个元素的文本内容包含字符串1.2.4 ,第2个中括号表示相对于groupId使用../向上跳元素,那么../就是dependencies元素了,然后这个元素下的artifactId元素。即../artifactId=dependencies/artifactId,后面就和前面那个规则一样,就是指text内容包含 有fastjson关键词的。3个中括号就是连续满足3个条件
再说一个实例:
mybatis SQL拼接 //*[contains(@*,'$')][contains(text(),'$') and contains(text(),'=')] |
//*表示任何元素,@*中的@表示元素的属性,这里的@*就是任何的属性,连起来就是任何元素的任何属性的text 包含有$符,且 包含等于号。因为我观察了mybatis的sql注入,无非就是$和=的特点
其他如果有需求大家可以在
https://github.com/xsser/pmd-security-rules
提issue,我来编写规则
明天再继续写规则
本文始发于微信公众号(xsser的博客):如何使用pmd编写xpath rule来检测安全合规问题
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论