標籤:

在 Node.js 中,避免命令注入攻擊

在 Node.js 中,避免命令注入攻擊

來自專欄 前端搬運工Avoiding Command Injection in Node.js?

blog.liftsecurity.io

在這篇文章中,我們談論下在 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,可以讓我知道她的位置替她報警?
潛水時迎面遇到密集魚群該如何應對?

TAG:Nodejs | 安全 |