基于正则的URL匹配安全性考虑
Posted | archive
reddit上讨论的这个问题比较有意思。
假设django里有这样一个URL匹配
(r'^(\d\d\d\d)/$', 'jl6.core.views.showyear'),
那么下面两个网址能否命中这个匹配呢?
http://james.lab6.com/%D9%A2%D9%A0%D9%A0%D9%A8/
http://james.lab6.com/%F0%9D%9F%AE%F0%9D%9F%AC%F0%9D%9F%AC%F0%9D%9F%B4/
结果是可以命中的。
第一个URL是/٢٠٠٨/,包含了4个unicode字符
٢ U+0662 ARABIC-INDIC DIGIT TWO
٠ U+0660 ARABIC-INDIC DIGIT ZERO
٠ U+0660 ARABIC-INDIC DIGIT ZERO
٨ U+0668 ARABIC-INDIC DIGIT EIGHT
第二个URL是/𝟐𝟎𝟎𝟖/:
U+1D7D0 MATHEMATICAL BOLD DIGIT TWO
U+1D7CE MATHEMATICAL BOLD DIGIT ZERO
U+1D7CE MATHEMATICAL BOLD DIGIT ZERO
U+1D7D6 MATHEMATICAL BOLD DIGIT EIGHT
\d
能匹配这些字符并不是python的bug,因为Python能正确转换Unicode到对应数字
Python 2.6.3 (r263rc1:75186, Oct 2 2009, 20:40:30) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> int(u'\u0661')
1
>>> int(u'1')
1
结论:以后多用[0-9]
少用\d
更新1:
MATHEMATICAL BOLD DIGIT这个Unicode太威武了,MySQL没法存,我的blog第一次保存直接被截断了。。。我说怎么blog后面一大段内容不见了。。。用这个特性来防止被复制粘贴,被小偷程序采集入库应该很爽。
换成HTML标记保存下来了,可是markdown语法的空四格代码段又不支持HTML标记。。。
Comments