无法使用ModSecurity访问命名空间内的XML元素
ModSecurity规则XML命名空间匹配问题解决
问题描述
配置了以下ModSecurity规则:
SecRule REQUEST_URI "@beginsWith /testing-endpoint" "id:10003,phase:2,t:lowercase,log,msg:'TESTING_SOAP BLOCKED',deny,chain" SecRule XML:/soap12:Envelope/soap12:Body/level1/level2/data ".*" "id:11003,xmlns:level1=http://www.erpx.example.com/,xmlns:soap12=http://www.w3.example.org/2003/05/soap-envelope,xmlns:xsd=http://www.w3.example.org/2001/XMLSchema,xmlns:xsi=http://www.w3.example.org/2001/XMLSchema-instance"
目标是匹配XML请求载荷中的<data>AAAA-BBBB</data>:
<?xml version="1.0" encoding="ISO-8859-1"?> <soap12:Envelope xmlns:xsi=http://www.w3.example.org/2001/XMLSchema-instance xmlns:xsd=http://www.w3.example.org/2001/XMLSchema xmlns:soap12=http://www.w3.example.org/2003/05/soap-envelope> <soap12:Body> <level1 xmlns=http://www.erpx.example.com/> <level2> <data>AAAA-BBBB</data> <!-- Trying to access this --> <dataOther>Testing Purposes Only</dataOther> </level2> </level1> </soap12:Body> </soap12:Envelope>
当前规则执行失败,但移除<level1 xmlns=http://www.erpx.example.com/>中的xmlns属性后,规则可正常工作。相关日志片段:
[170006830474.797743] [/testing-endpoint] [4] (Rule: 11004) Executing operator "Rx" with param ".*" against XML:/soap12:Envelope/soap12:Body/level1/level2/data. [170006830474.797743] [/testing-endpoint] [4] Registered XML namespace href "http://www.erpx.example.com/" prefix "level1" [170006830474.797743] [/testing-endpoint] [4] Registered XML namespace href "http://www.w3.org/2003/05/soap-envelope" prefix "soap12" [170006830474.797743] [/testing-endpoint] [4] Registered XML namespace href "http://www.w3.org/2001/XMLSchema" prefix "xsd" [170006830474.797743] [/testing-endpoint] [4] Registered XML namespace href "http://www.w3.org/2001/XMLSchema-instance" prefix "xsi" [170006830474.797743] [/testing-endpoint] [4] Rule returned 0.
需要解决:如何正确访问带命名空间的<data>节点?
问题原因
当<level1>节点声明xmlns=http://www.erpx.example.com/时,该命名空间会成为默认命名空间,作用于自身及所有未指定前缀的子节点(level2、data都属于这个命名空间)。而原规则中仅给level1指定了命名空间前缀,level2和data未关联任何命名空间,ModSecurity会认为它们属于无命名空间节点,因此匹配失败。
解决方法
方法1:给子节点添加命名空间前缀
修改XML路径,给level1、level2、data都加上level1前缀(对应注册的命名空间):
SecRule REQUEST_URI "@beginsWith /testing-endpoint" "id:10003,phase:2,t:lowercase,log,msg:'TESTING_SOAP BLOCKED',deny,chain" SecRule XML:/soap12:Envelope/soap12:Body/level1:level1/level1:level2/level1:data ".*" "id:11003,xmlns:level1=http://www.erpx.example.com/,xmlns:soap12=http://www.w3.example.org/2003/05/soap-envelope,xmlns:xsd=http://www.w3.example.org/2001/XMLSchema,xmlns:xsi=http://www.w3.example.org/2001/XMLSchema-instance"
方法2:声明默认命名空间
在规则中用xmlns:=语法声明默认命名空间,这样路径中无前缀的节点会自动匹配该命名空间:
SecRule REQUEST_URI "@beginsWith /testing-endpoint" "id:10003,phase:2,t:lowercase,log,msg:'TESTING_SOAP BLOCKED',deny,chain" SecRule XML:/soap12:Envelope/soap12:Body/level1/level2/data ".*" "id:11003,xmlns:=http://www.erpx.example.com/,xmlns:soap12=http://www.w3.example.org/2003/05/soap-envelope,xmlns:xsd=http://www.w3.example.org/2001/XMLSchema,xmlns:xsi=http://www.w3.example.org/2001/XMLSchema-instance"
方法3:通配符匹配任意命名空间(仅临时测试)
用*:前缀匹配任意命名空间的节点,这种方式可能误匹配,不建议生产环境使用:
SecRule REQUEST_URI "@beginsWith /testing-endpoint" "id:10003,phase:2,t:lowercase,log,msg:'TESTING_SOAP BLOCKED',deny,chain" SecRule XML:/soap12:Envelope/soap12:Body/*:level1/*:level2/*:data ".*" "id:11003,xmlns:soap12=http://www.w3.example.org/2003/05/soap-envelope,xmlns:xsd=http://www.w3.example.org/2001/XMLSchema,xmlns:xsi=http://www.w3.example.org/2001/XMLSchema-instance"
内容的提问来源于stack exchange,提问作者lostsource
相关产品推荐
相关产品推荐

