Node.js 權限模型 (Permission Model):為你的程式碼套上枷鎖

在傳統的 Node.js 環境中,只要執行了一個腳本,該腳本就擁有與執行用戶相同的完整權限。這意味著一個簡單的第三方套件,如果帶有惡意程式碼,就能讀取你的 .ssh/id_rsa 或是對外發送敏感資料。

Node.js 20.0.0 開始,官方引入了實驗性的 權限模型 (Permission Model),允許開發者以「精細」的角度限制程式對檔案系統、網路以及子行程的存取權。

為什麼你需要權限模型?

  1. 防範供應鏈攻擊:限制沒聽過的套件讀取特定的機密檔案。
  2. 安全沙箱化:在執行不受信任的腳本(如外掛系統)時,確保它們不會危害系統主體。
  3. 符合合規要求:在銀行或高安全等級環境中,明確宣告程式碼的存取邊界。

核心旗標:如何開啟權限控制?

要啟動權限模型,必須在啟動命令中加入 --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('權限不足!');
}

注意事項與局限

  1. 實驗性質 (Experimental):API 可能會在未來的版本中變動。
  2. 效能損耗:每次檔案讀寫都會經過權限檢查,對極度依賴 I/O 的純計算任務可能會有微幅效能影響。
  3. 不保證絕對安全:雖然這提供了一層強大的防護,但安全是一個多維度的議題(如 CPU 漏洞或記憶體攻擊依然存在)。
警告:權限模型無法阻止已經透過 native modules (C++) 逃脫 Node.js 執行環境的程式碼,因此在引入原生擴充套件時仍需保持謹慎。

總結

  1. 權限模型 是 Node.js 邁向企業級安全的重要里程碑。
  2. 使用 --allow-fs-*--allow-net 能極大化地縮小攻擊表面積。
  3. 掌握這項技術,能讓你開發的服務在面對潛在威脅時更加強韌。