在 Node.js 中,避免命令注入攻擊
來自專欄 前端搬運工Avoiding Command Injection in Node.js
在這篇文章中,我們談論下在 Node.js 中以正確的方式調用系統命令,從而避免普遍的安全風險 - 命令注入(command Injection)。
child_process.exec 一個我們經常使用的調用。傳入一個字元串命令,如果有錯誤或者有結果會通知你。
下面是一個典型的調用系統命令的方式。
child_process.exec(ls, (err, data) => { console.log(data);});
如果我們將用戶的輸入作為傳入的命令會發生什麼?最常見的情況是,用用戶的輸入通過字元串連接的方式。但是我之前學到過,如果你用字元串連接的方式將數據從一個系統到另一個系統,你可能會有糟糕的一天。
let path = "user input";child_process.exec(ls -l + path, (err, data) => { console.log(data);});
為什麼字元串連接為成為一個問題?
因為底層,child_process 發起一個調用執行 /bin/sh ,而不是目標程序。發送的命令在新衍生的 /bin/sh 進程作為一個 shell 命令,child_process.exec 有一個容易被誤解的名字 - 它是一個 bash 解釋器,而不是一個程序啟動器。這意味著如果命令包含用戶的輸入,shell 字元可能有毀滅性的破壞。
[pid 25170] execve("/bin/sh", ["/bin/sh", "-c", "ls -l user input"], [/* 16 vars */]
例如:一個攻擊者可能在語句的結尾使用 ;,並且開啟另外一個,他們可能使用反引號或者 $() 來運行一個子命令。很多潛在的濫用。
因此如何才能正確地做這件事?
execFile / spawn
spawn 和 execFile 調用接收額外的作為數組的命令參數,沒有在 shell 環境下執行,不操縱原先預定的命令來運行。
將之前例子改為 spawn 和 execFile 實現,看看系統調用的區別,為什麼它不容易被命令注入。
child_process.execFile
const child_process = require(child_process);let path = ".";child_process.execFile(/bin/ls, [-l, path], function(err, result){ console.log(result);});
系統調用運行了
[pid 25565] execve("/bin/ls", ["/bin/ls", "-l", "."], [/* 16 vars */]
同樣的例子用 spawn 實現
const child_process = require(child_process);let path = ;let ls = child_process.spawn(/bin/ls, [-l, path]);ls.stdout.on(data, (data) => { console.log(data.toString());});
系統調用是這樣運行的
[pid 26883] execve("/bin/ls", ["/bin/ls", "-l", "."], [/* 16 vars */]
當使用 spawn 或者 execFile,我們的目標程序是傳入 execve 的第一個參數。這意味著用戶不能在 shell 中運行子命令,因為 /bin/ls 遇到反引號或者分號或者 pipe 符時不知道要做什麼。是 /bin/bash 解釋這些命令。如果你熟悉的話,這是類似於使用參數化和基於字元串的 SQL 查詢。
然而確實是一個警告:使用 spawn 和 execFile 並不總是安全的。例如,使用 spawn 和 execFile 運行 /bin/find 並且將用戶的輸入作為參數會導致完整的系統接管。find 命令有配置選項允許對文件進行讀寫。
這裡有些在 Node.js 中運行系統命令的建議:
- 避免使用 child_process.exec,如果有任何依賴於用戶輸入的參數,那麼就不要用這個命令。
- 如果可能的話,不要讓用戶往命令中傳遞參數。但是用 spawn 和 execFile 時典型的值是可以的,但是用戶控制的 select 選項不是一個好主意。
- 如果你允許用戶控制 select 的 option,看 option 的選項,決定那些值是安全的,只允許通過白名單的選項。
謝謝閱讀?。
推薦閱讀:
※為什麼飛機上不能開手機?如果打開手機網路上網會有什麼影響?
※燃氣案例分享
※經歷不可抗力是一種什麼體驗
※女友在澳洲,我在國內,女友遇到危險怎麼辦?有沒有好用的救援APP,可以讓我知道她的位置替她報警?
※潛水時迎面遇到密集魚群該如何應對?