Node.js 權限模型 (Permission Model):為你的程式碼套上枷鎖
在傳統的 Node.js 環境中,只要執行了一個腳本,該腳本就擁有與執行用戶相同的完整權限。這意味著一個簡單的第三方套件,如果帶有惡意程式碼,就能讀取你的 .ssh/id_rsa 或是對外發送敏感資料。
從 Node.js 20.0.0 開始,官方引入了實驗性的 權限模型 (Permission Model),允許開發者以「精細」的角度限制程式對檔案系統、網路以及子行程的存取權。
為什麼你需要權限模型?
- 防範供應鏈攻擊:限制沒聽過的套件讀取特定的機密檔案。
- 安全沙箱化:在執行不受信任的腳本(如外掛系統)時,確保它們不會危害系統主體。
- 符合合規要求:在銀行或高安全等級環境中,明確宣告程式碼的存取邊界。
核心旗標:如何開啟權限控制?
要啟動權限模型,必須在啟動命令中加入 --experimental-permission 旗標。
1. 限制檔案讀取 (--allow-fs-read)
如果你只希望程式能讀取 ./public 資料夾,可以使用:
node --experimental-permission --allow-fs-read=./public index.js
如果程式碼嘗試執行 fs.readFileSync('/etc/passwd'),Node.js 會立即拋出 ERR_ACCESS_DENIED 錯誤。
2. 限制檔案寫入 (--allow-fs-write)
node --experimental-permission --allow-fs-write=/tmp/myapp index.js
3. 限制網路連線 (--allow-net)
這可以防止程式碼將資料外洩到不明伺服器:
# 只允許對 google.com 進行連線
node --experimental-permission --allow-net=google.com index.js
在程式中檢查權限
除了在啟動時指定,我們也可以透過 process.permission 物件在程式運行時檢查目前的權限狀態:
if (process.permission.has('fs.read', '/etc/private.key')) {
console.log('我有權限讀取敏感金鑰');
} else {
console.error('權限不足!');
}
注意事項與局限
- 實驗性質 (Experimental):API 可能會在未來的版本中變動。
- 效能損耗:每次檔案讀寫都會經過權限檢查,對極度依賴 I/O 的純計算任務可能會有微幅效能影響。
- 不保證絕對安全:雖然這提供了一層強大的防護,但安全是一個多維度的議題(如 CPU 漏洞或記憶體攻擊依然存在)。
警告:權限模型無法阻止已經透過 native modules (C++) 逃脫 Node.js 執行環境的程式碼,因此在引入原生擴充套件時仍需保持謹慎。
總結
- 權限模型 是 Node.js 邁向企業級安全的重要里程碑。
- 使用
--allow-fs-*與--allow-net能極大化地縮小攻擊表面積。 - 掌握這項技術,能讓你開發的服務在面對潛在威脅時更加強韌。