在基於PCRE實現的正則引擎中,我們常使用“m表示multi-line、s表示single-line”。
multi-line表示按行來匹配正則,可以理解為以換行符為切割,對每行進行正則匹配然后進行or運算出結果。
中single-line的意思是將待匹配的文本視為一行,換行符不再作為“換行”的標志。
這在日常使用中也經常會出現由首尾界定符產生的小bug,比如下面這一個。
<?php if(preg_match('/^a[a-z]+z$/m', $_GET['input'])) { //匹配a開頭 z結尾 echo $_GET['input']; }
正則匹配中我們常使用`^`和`$`來界定正則匹配的首尾,但這兩個的符號本身的含義其實是代表了“行的開頭和結尾”,也就意味着如果你輸入一個%0a換行,后面就可以輸入任何字符也能完成匹配。
比如上面的代碼本身的含義可能是:用戶輸入一個以a開頭,以z結尾的中間可以有若干字母的字符串。但因為指定了m修飾符,導致用戶可以傳入:
input=abcz%0a<svg%20onload=alert(1)>
來繞過檢測。 有些地方是可以有效的。