淺析node應(yīng)用的timing-attack安全漏洞
前言
假如你在項(xiàng)目中遇到過 eslint 報(bào)錯(cuò) Potential timing attack ,不可忽視!這是一個(gè)涉及到安全的問題:時(shí)序攻擊。
eslint 報(bào)錯(cuò)原因
首先eslint引入了一個(gè)叫做eslint-plugin-security的插件,這個(gè)插件有助于識(shí)別出潛在的安全問題,但同時(shí)也會(huì)產(chǎn)生誤報(bào)的問題,附上插件 源碼地址。
var keywords = '((' + [ 'password', 'secret', 'api', 'apiKey', 'token', 'auth', 'pass', 'hash' ].join(')|(') + '))'; var re = new RegExp('^' + keywords + '$', 'im'); function containsKeyword (node) { if (node.type === 'Identifier') { if (re.test(node.name)) return true; } return } if (node.test.operator === '==' || node.test.operator === '===' || node.test.operator === '!=' || node.test.operator === '!==') { // 在這里 console 出錯(cuò)誤 }
首先這個(gè)插件會(huì)判斷本次的運(yùn)算符是否為 ==、===、!=、!==其中一種,其次檢查標(biāo)識(shí)符(字段名)是否包含特殊字符串password、secret、api、apiKey、token、auth、pass、hash,如果同時(shí)滿足二者情況,eslint 就會(huì)編譯報(bào)錯(cuò) Potential timing attack。
攻擊定義
timing attack:時(shí)序攻擊,屬于側(cè)信道攻擊 / 旁路攻擊,側(cè)信道攻擊指的是利用信道外的信息,比如加解密的數(shù)據(jù)、數(shù)據(jù)比較時(shí)間、密文傳輸?shù)牧髁亢屯緩竭M(jìn)行攻擊的方式,相當(dāng)于是“旁敲側(cè)擊”。
攻擊點(diǎn)
首先講講js比較兩個(gè)字符串大小的原理:
- 判斷字符串長度是否為0,如果為0,就可以直接比較出結(jié)果;反之,進(jìn)入到第二步。
- 字符串是由一個(gè)個(gè)字符組成,通過每個(gè)字符的charCode進(jìn)行比較。
- 在第二步中,只要出現(xiàn)一個(gè)字符不同,就 return false,剩余的字符不再做比較。
單個(gè)字符的比較是很快的,攻擊者可以細(xì)化測量時(shí)間精度到微秒,通過響應(yīng)時(shí)間的差異推算出是從哪一個(gè)字符開始不用的,這樣一次次實(shí)驗(yàn)或者用 Python 寫個(gè)腳本去跑,就可以試出正確的密碼,密碼破解的難度也降低了不少。
容易受攻擊的寫法
if (user.password === password) { return { state: true }; // 登錄成功 }
防御措施
每次不同的輸入會(huì)造成處理時(shí)間的不同。為了防止它,我們需要使字符串比較花費(fèi)相同的時(shí)間量,無論輸入的密碼是什么。
不容易受攻擊的寫法
系統(tǒng)中每一個(gè)密碼的長度是固定的,每次比較密碼是否相同時(shí),使用正確密碼的長度作為比較次數(shù),使用異或比較每一個(gè)字符的 Unicode 編碼是否相等,并且把每一次的比較結(jié)果存放到一個(gè)數(shù)組中,最后再判斷數(shù)組的每一個(gè)元素是否為0(為 0 表示兩個(gè)字符相同)。
// psdReceived 為用戶輸入密碼; // psdDb 為系統(tǒng)中存儲(chǔ)的正確用戶密碼 const correctUser = (psdDb, psdReceived) => { const state = []; for (let i = 0; i < psdDb.length; ++i) { if (!psdReceived[i]) { state.push(false); } else { state.push(psdReceived.charCodeAt(i) ^ psdDb.charCodeAt(i)); } } return state.length !== 0 && state.every(item => !item); }
三方包推薦
也可以使用 cryptiles 這個(gè) npm 模塊來解決這個(gè)問題
import cryptiles from 'cryptiles'; ...... return cryptiles.fixedTimeCimparison(passwordFromDb, passwordReceived);
相關(guān)文章
前端常見面試題之a(chǎn)sync/await和promise的區(qū)別
async/await是異步代碼的新方式,以前的方法有回調(diào)函數(shù)和Promise,下面這篇文章主要給大家介紹了關(guān)于前端常見面試題之a(chǎn)sync/await和promise區(qū)別的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-07-07Node.js 中exports 和 module.exports 的區(qū)別
這篇文章主要介紹了Node.js 中exports 和 module.exports 的區(qū)別的相關(guān)資料,需要的朋友可以參考下2017-03-03node.js項(xiàng)目如何創(chuàng)建websocket模塊
這篇文章主要介紹了node.js項(xiàng)目如何創(chuàng)建websocket模塊問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-09-09Node.js在child_process域和錯(cuò)誤冒泡及捕獲實(shí)踐
這篇文章主要為大家介紹了Node.js在child_process域和錯(cuò)誤冒泡及捕獲實(shí)踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11Node.js創(chuàng)建HTTP文件服務(wù)器的使用示例
我們的目的比較簡單,使用Node.js創(chuàng)建一個(gè)HTTP協(xié)議的文件服務(wù)器,你可以使用瀏覽器或其它下載工具到文件服務(wù)器上下載文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-05-05Node.js如何實(shí)現(xiàn)注冊郵箱激活功能 (常見)
今天了解了node如何實(shí)現(xiàn)郵箱激活功能,這個(gè)功能非常常見,當(dāng)我們注冊一個(gè)賬號(hào)時(shí),肯定會(huì)有這步,下面看下如何實(shí)現(xiàn)這個(gè)功能2017-07-07安裝 node-Sass 報(bào)錯(cuò)的解決記錄(三步解決法)
本文主要介紹了安裝 node-Sass 報(bào)錯(cuò)的解決記錄(三步解決法),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05