如何防止JavaScript中的正則表達式回溯
正則表達式是用于在軟件應用程序中操作和驗證文本的強大工具。然而,某些正則表達式模式可能容易受到回溯的影響,這可能會導致超線性運行時,并可能導致DoS攻擊。在本文中,我們將探討什么是回溯、它如何導致性能問題以及如何在正則表達式中防止回溯。
正則表達式中的回溯是什么
回溯是正則表達式引擎用來處理包含可選或重復子模式的復雜模式的技術。當正則表達式模式包含可選或重復的子模式時,引擎可能需要嘗試子模式的多種組合才能找到匹配項。這個過程稱為回溯。
例如,有以下正則表達式:
/^[a-zA-Z0-9\s]+$/
此正則表達式應匹配僅包含字母數(shù)字字符和空格的任何字符串。然而,它很容易受到回溯的影響,因為+
字符類后面的運算符允許字符類的任意數(shù)量的重復。
攻擊者可以通過發(fā)送包含一長串不匹配字符的惡意搜索查詢來利用此漏洞,例如:
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaab
該字符串包含 30 個a
字符,后跟一個b
. 當正則表達式引擎嘗試匹配該字符串時,它將前 30 個a
字符與字符類匹配,但無法匹配b
字符。然后,引擎將回溯并嘗試字符類的不同組合,直到匹配整個字符串或耗盡所有可能的組合。
在本例中,字符串中有 31 個字符,因此有 2 種可能的字符類組合可供嘗試。這可能需要很長的時間,可能會導致服務器遭受 DoS
攻擊。
為了防止此漏洞,您可以修改正則表達式以使用*
運算符代替+
運算符,如下所示:
/^[a-zA-Z0-9\s]*$/
使用*
可以使正則表達式不易受到回溯并降低 DoS
攻擊的風險,因為它減少了正則表達式引擎需要探索的可能路徑的數(shù)量。
+
的意思是“一個或多個”,而*
的意思是“零個或多個”。使用+
時,正則表達式引擎必須在放棄之前嘗試與模式匹配的所有可能的字符組合。這可能會導致回溯并導致引擎花費過多的時間來嘗試匹配字符串,從而更容易受到 DoS
攻擊。
另一方面,使用*
使子模式成為可選,這意味著如果不匹配,正則表達式引擎可以完全跳過它。這減少了引擎需要探索的可能路徑的數(shù)量。
回溯如何導致性能問題
回溯可能會通過兩種方式導致性能問題:
- 超線性運行時間:回溯可能會導致正則表達式模式的運行時間變得超線性,這意味著匹配模式所需的時間增長速度快于輸入字符串的長度。這可能會使該模式對于長輸入字符串極其緩慢,并且如果將該模式應用于不受信任的用戶輸入,則可能會導致
DoS
攻擊。 - 高內存使用量:回溯還會導致正則表達式引擎使用大量內存,特別是當模式包含嵌套的可選或重復的子模式時。這可能會導致應用程序內存不足并崩潰。
如何防止正則表達式模式中的回溯
為了防止正則表達式模式中的回溯,我們需要以避免可選或重復子模式的方式設計思路。以下是我們可以使用的一些技巧:
使用特定的字符類:
使用特定的字符類可以通過限制可以匹配子模式的字符數(shù)來幫助防止回溯。例如,/[a-z]/
匹配從 a
到 z
的任何小寫字母。
使用非捕獲組
使用非捕獲組可以通過避免不必要的內存分配來幫助防止回溯。例如,/(?:ab)+/
匹配字符串ab
的一次或多次出現(xiàn),而不創(chuàng)建捕獲組。
使用原子組
使用原子組可以通過使子模式成為非可選來幫助防止回溯。例如,/a(?>b|c)/
匹配包含字母a
后跟b
或c
的字符串,而不進行回溯。
使用多個子模式而不將其中任何一個設為可選
使用多個子模式而不將其中任何一個設為可選可以通過限制正則表達式引擎需要探索的可能路徑的數(shù)量來幫助防止回溯。例如,/^(ab|cd|ef)$/
匹配ab
、cd
或ef
字符串,而不進行回溯。
使用所有格子模式:
使用所有格子模式可以通過使子模式成為非可選來幫助防止回溯。所有格子模式由語法(?+...
)表示。例如,/a(?+b)/
匹配包含字母a
后跟字母b
的字符串,而不進行回溯。
使用惰性量詞:
使用惰性量詞可以通過使子模式可選來幫助防止回溯,但仍然可以防止回溯。惰性量詞由+?or*?
符號表示。例如,/a+?/
匹配一??次或多次出現(xiàn)的字母a
,但使用惰性量詞來防止回溯。
使用有界量詞:
使用有界量詞可以通過限制子模式的重復次數(shù)來幫助防止回溯。有界量詞由語法{min,max}
表示,其中min
和max
是指定最小和最大重復次數(shù)的整數(shù)。例如,/a{1,3}/
匹配包含重復一到三次的字母a
的字符串,而不回溯。
到此這篇關于如何防止JavaScript中的正則表達式回溯的文章就介紹到這了,更多相關JavaScript 正則表達式回溯內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
JavaScript實現(xiàn)點擊出現(xiàn)子菜單效果
這篇文章主要為大家詳細介紹了JavaScript實現(xiàn)點擊出現(xiàn)子菜單,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2021-02-02