漏洞描述:
扫描漏洞如下:
代码:
// In IE6, the hash fragment and search params are incorrect if the // fragment contains `?`. getSearch: function() { var match = this.location.href.replace(/#.*/, '').match(/\?.+/); return match ? match[0] : ''; }, |
// Update the hash location, either replacing the current entry, or adding // a new one to the browser history. _updateHash: function(location, fragment, replace) { if (replace) { var href = location.href.replace(/(javascript:|#).*$/, ''); location.replace(href + '#' + fragment); } else { // Some browsers require that `hash` contains a leading #. location.hash = '#' + fragment; } } |
ReDoS(Regularexpression Denial of Service)正则表达式拒绝服务攻击。开发人员使用了正则表达式来对用户输入的数据进行有效性校验,当编写校验的正则表达式存在缺陷或者不严谨时, 攻击者可以构造特殊的字符串来大量消耗服务器的系统资源,造成服务器的服务中断或停止。
每个恶意的正则表达式模式应该包含:使用重复分组构造、在重复组内会出现、重复、交替重叠。
有缺陷的正则表达式会包含如下部分。
(a+)+
([a-zA-Z]+)*
(a|aa)+
(a|a?)+
(.*a){x} | for x > 10
注意: 这里的a是个泛指。
一些实际业务场景中会用到的缺陷正则:
英文的个人名字 Java类名 Email格式验证 多个邮箱地址验证 复数验证 模式匹配 使用python来进行测试有缺陷的正则示例
|
解决方案:
防范手段只能降低风险而不能百分百消除ReDoS这种威胁。
1. 降低正则表达式的复杂度, 尽量少用分组;
2. 严格限制用户输入的字符串长度(特定情况下)。
对本次测试漏洞进行分析,似乎并不存在重复分组或嵌套分组的正则表达式,为了应对安全测试,建议解决方案如下:
方案1 | 使用{m, n}替代“*”、“+”等,限制匹配的字符数量,如: 将 var href = location.href.replace(/(javascript:|#).*$/, ''); 修改为 var href = location.href.replace(/(javascript:|#).{0, 1000}$/, ''); |
方案2 | 使用字符串截取函数slice()或substring(),替代replace()函数,如: 将 var href = location.href.replace(/(javascript:|#).*$/, ''); 修改为 var lochref = location.href; var idxnum = lochref.indexof(“javascript:”); if(idxnum == -1) idxnum = lochref.indexof(“#”); var href = idxnum == -1? lochref : lochref.slice(0, idxnum + 1); |
参考资料:
Regular expression Denial of Service - ReDoS
浅析ReDoS的原理与实践
Location 对象
正则表达式基础
js字符串截取函数slice()、substring()、substr()