案例中使用到的xml文件,名称为test.xml
<?xml version="1.0" encoding="UTF-8"?> <ContentList id="0"> <Content id="1001" class="style" name="lisi"> <name id=‘44‘>张三</name> <age>20</age> </Content> <Content id="1002"> <name id=‘22‘>张三g</name> <phone>134222225555</phone> </Content> <ContentTwo> <name>王五</name> <qq>123456</qq> </ContentTwo> </ContentList>
使用到的jar包的maven依赖
<!-- https://mvnrepository.com/artifact/jaxen/jaxen --> <dependency> <groupId>jaxen</groupId> <artifactId>jaxen</artifactId> <version>1.1-beta-6</version> </dependency> <!-- https://mvnrepository.com/artifact/dom4j/dom4j --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency>
xpath技术在java中的使用
package xyz.xpath; import java.io.File; import java.io.FileOutputStream; import java.util.List; import org.dom4j.Document; import org.dom4j.Element; import org.dom4j.Node; import org.dom4j.io.OutputFormat; import org.dom4j.io.SAXReader; import org.dom4j.io.XMLWriter; public class DemoA { public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("/root/桌面/test.xml")); /** * 代表 xpathFormat代表xpaht的语法 */ String xpathFormat=""; /** * / 表示绝对路径,表示从xml的一个根位置或子元 */ xpathFormat="/contentList"; xpathFormat="/contentList/content"; /** * // 表示相对路径 */ xpathFormat="//content/name"; xpathFormat="/contentList//name"; /** * * 表示通配符 */ xpathFormat ="/contentList/*"; //根标签contentList下的所有子标签 xpathFormat = "/contentList//*";//根标签contentList下的所有标签(不分层次结构) /** * [] 条件 */ xpathFormat ="//content[@id]"; //带有id属性 xpathFormat ="//content[2]"; // 第二个 content 标签 xpathFormat ="//content[last()]"; //最后一个 content 标签 /** * @ 表示属性,表示选择属性节点 */ xpathFormat = "//@id"; //选择id属性节点对象,返回的是Attribute对象 xpathFormat= "//content[not(@id)]";//选择不包含id属性的content标签节点 xpathFormat = "//content[@id=‘002‘]";//选择id属性值为002的content标签 xpathFormat = "//content[@id=‘001‘ and @name=‘eric‘]";// 选择id属性值为001,且name属性为eric的content标签 /** * text() 表示选择文本内容 */ xpathFormat="//name/text()"; xpathFormat="//name[text()=‘张三‘]"; List<Node> selectNodes = doc.selectNodes(xpathFormat); //遍历输出查询到的结果 for (Node node : selectNodes) { System.out.println(node.getText()); } // 修改xml文件的内容 xpathFormat="//name[text()=‘王五‘]"; Element el = (Element)doc.selectSingleNode(xpathFormat); el.addAttribute("flag", "student"); //输出xml文件 FileOutputStream outputStream=new FileOutputStream("/root/桌面/testC.xml"); OutputFormat createPrettyPrint = OutputFormat.createPrettyPrint(); createPrettyPrint.setEncoding("utf-8"); XMLWriter xmlWriter=new XMLWriter(outputStream,createPrettyPrint); xmlWriter.write(doc); xmlWriter.close(); } }
xpath中的符号
有效运算符号 and or not() + - * div(除) mod(取余) = != < > <= >=
/ 绝对路径
// 相对路径
. 当前节点
.. 父节点
* 选择所有
[] 指定特定元素
| 或,选择多个路径
@ 用来取属性
xpath注入的危害
1,xpath是一种标准语言,只要使用xpath语法的web应用程序,都可能存在此漏洞。
2,危害性大,xpath语言集合可以引用xml文档的所有部分,且这种引用没有访问控制限制。
xpath注入实现
package xyz.xpath; import java.io.File; import java.util.List; import org.dom4j.Document; import org.dom4j.Node; import org.dom4j.io.SAXReader; public class DemoB { public static void main(String[] args) throws Exception { Document doc = new SAXReader().read(new File("/root/桌面/test.xml")); String inputString = "";// 表示用户的输入 String xpathFormat = "";// xpath查询语句 inputString = "张三"; //正常的输入 inputString = "李四‘ or 1=1 or ‘a‘=‘b"; //XPath注入 xpathFormat = "//name[text()=‘" + inputString + "‘]"; // 拼接XPath语句 System.out.println(xpathFormat); List<Node> selectNodes = doc.selectNodes(xpathFormat); for (Node node : selectNodes) { System.out.println(node); } } }
XPath注入的预防
XPath注入和sql注入一样,只要在程序开发的时候对输入的内容进行校验,就可以轻松的防御。
1,检查客户端输入内容的长度,类型,格式
2,特殊字符进行转义
3,参数化XPath查询,而且这种方法子需要编译一次,可以节省CPU使用量
一种有效防止SQL注入相关问题的技术是参数化。参数化能确保将用户指定的数据以参数的形式传递给API,这样数据就不会被解释为可执行内容了。遗憾的是,Java SE目前缺乏一个类似于XPath查询的接口。不过,通过使用XQuery这样的接口,XPath可以模拟SQL参数化。XQuery支持将查询语句写入运行时环境中的一个单独文件中。
原文:https://www.cnblogs.com/sinosecurity/p/15028136.html