ReDos(正則表達(dá)式拒絕服務(wù))

我們平時開發(fā)時,會經(jīng)常使用到正則表達(dá)式進(jìn)行對數(shù)據(jù)檢驗(yàn),因?yàn)檫@樣很方便快捷。但是與此同時,卻悄悄地隱含了一些安全問題。下面我們就說一說ReDos,即正則表達(dá)式拒絕服務(wù)。此安全問題,常常是出現(xiàn)在web api請求檢驗(yàn)時,開發(fā)者為貪圖方便快捷而使用正則表達(dá)式對用戶請求的數(shù)據(jù)進(jìn)行簡單校驗(yàn)。
以下以Nodejs為案例,如下面代碼:

let regx = /^([a-z0-9A-Z]+[-|_|\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\.)+[a-zA-Z]{2,}$/;  //校驗(yàn)Email的正則
let str = "nnnnnnnnnardy";  //長度為13的字符串
console.time("redos");
regx.test(str);
console.timeEnd("redos");

我的電腦是windows 10 ,臺式機(jī),8G 內(nèi)存,4核心,測得的平均耗時為0.245ms;
接下來,我們把要檢驗(yàn)的字符串長度加大:

let str = "nnnnnnnnnnnnnnnnardy";  //長度為20的字符串

此時測試的平均耗時為5ms;我們繼續(xù)把字符串長度增大:

let str = "nnnnnnnnnnnnnnnnnnnnnnnnnnardy";  //長度為30的字符串

此時測試的平均耗時為5s;我們繼續(xù)把字符串長度增大:

let str = "nnnnnnnnnnnnnnnnnnnnnnnnnnnardy";  //長度為31的字符串

Oh My God!此時測試的最高耗時居然達(dá)到了10s;我還試了35位長度的字符串,反正我等了2分鐘沒等到結(jié)果返回。

試想,如果我們的web接口,也加入了類似的正則校驗(yàn),那僅僅是因?yàn)橛脩舻腅mai的名稱長了點(diǎn),就足以影響到服務(wù)器的請求接收,這對項(xiàng)目來說是一個安全問題了。

為什么會出現(xiàn)ReDos??

原因是:大多數(shù)正則表達(dá)式引擎的工作原理相似,都會首先對合適的字符串進(jìn)行嘗試多匹配,一次失敗了,會嘗試下一個可能的匹配,如果所有可嘗試匹配情況都失敗后,就會進(jìn)行回溯,看是否有其他方法來消化前一個字符,如果匹配路徑太深且發(fā)現(xiàn)最后不匹配,又或者有多種匹配路徑,則最后回溯的步驟可能會變得非常大,從而導(dǎo)致了災(zāi)難性的回溯結(jié)果。

建議

  1. 不要對用戶輸入的或不確定長度的數(shù)據(jù)進(jìn)行正則檢驗(yàn)
  2. 盡可能找到適合的替代方法

附注

因?yàn)楦鞣N開發(fā)語言都有正則表達(dá)式,且實(shí)現(xiàn)方式相似,所以,ReDos并非局限于Nodejs一種語言。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容