使用Deno增強AWS Lambda的安全性
Deno是一種替代JavaScript運行時的方案,于2020年發布。最近我注意到對它的興趣越來越多,它具有一些吸引人的特點:
- 避免安裝依賴項的需求
- 廣泛支持Web標準API
- 開箱即用的TypeScript支持
- 全功能工具集
- 精細的權限檢查
- 更安全的NPM包
- 高性能
其中吸引我注意的特性是精細的權限檢查和更安全的NPM包的概念。軟件供應鏈攻擊在過去幾年變得越來越頻繁,并且引起了更多關注。在JavaScript生態系統中,NPM是一個重要的目標。我試圖找到最近公開的NPM包數量,但沒有成功。NPM的主頁聲稱有1700萬開發者在使用它,這個數字我一點也不感到意外。
許多惡意包和代碼片段的共同特點是需要下載額外的依賴項或可執行文件。在這一點上,Deno可以發揮作用!除非經過允許,否則Deno不允許訪問環境變量、操作系統、文件系統、子進程或網絡。更好的是,對于其中的一些權限,您可以允許具體的訪問。例如,您可以允許訪問您的應用程序域名,但不允許其他訪問。如果您安裝了一個惡意包,它將很難下載其額外的依賴項或將數據泄漏出去。僅憑增加的安全性,Deno就成為一個有吸引力的選擇,也是我目前關注的重點。
在惡意包中隱藏的加密礦工對Lambda函數的影響有限;Lambda函數執行時間很短,很難獲得顯著的好處。數據泄漏和來自遠程源的腳本執行更可能成為問題。這兩者都需要訪問互聯網,而使用Deno,您有可能阻止這種訪問。
在AWS Lambda函數中使用Deno需要使用自定義運行時。您可以構建自己的運行時,也可以使用已經存在的運行時。如果您關注安全性,我建議保留一個現有運行時的副本,并仔細檢查更新或創建自己的運行時。對于這個概念驗證,我在我的AWS賬戶中部署了Deno的Serverless Application Repository (SAR)應用。我使用了提供的Lambda層和提供的.al2 Lambda運行時來創建我的Deno Lambda函數。我創建了一個名為index.ts的文件,其中包含一些基本的JavaScript代碼,用于請求兩個不同的網站并返回響應的HTTP狀態碼或捕獲的錯誤。然后,我更新了函數的配置以引用導出的handler函數。
typescript
export async function handler() {
const r1 = await makeRequest('https://deno.com');
const r2 = await makeRequest('https://example.com');
return { r1, r2 };
}
async function makeRequest(url: string) {
try {
const res = await fetch(url);
return res.status;
} catch (error) {
return error;
}
}
部署后,我從控制臺調用了我的Lambda函數,并收到了兩個HTTP 200的響應。由于自定義運行時的要求,Deno Lambda運行時默認允許所有的網絡和環境變量請求。Lambda自定義運行時通過與本地主機通信并通過環境變量接收初始化信息來工作。盡管有這個默認設置,我們可以縮小Deno的權限范圍并更嚴格地限制訪問。我使用的自定義運行時允許您通過修改DENO_PERMISSIONS環境變量來指定傳遞給Deno運行時的權限。默認值是--allow-env --allow-net。如果Lambda函數在應用程序中不需要任何網絡訪問,您可以使用如--allow-env --allow-net=127.0.0.1:9001的值,以僅允許所需的Lambda Runtime API通信。對于我的概念驗證,我將DENO_PERMISSIONS設置為--allow-env --allow-net=127.0.0.1:9001,deno.com,允許訪問deno.com但不允許訪問example.com。調用我的Lambda函數,我得到了以下結果:
json
{
"r1": 200,
"r2": {
"name": "PermissionDenied"
}
}
在本地運行Deno時,您將被要求允許訪問,但在Lambda函數中,當嘗試未授權的訪問時,將拋出錯誤。如果執行了一個惡意包,您可能會注意到意外的失敗或日志消息,但代碼的影響將受到限制。
使用這種方法需要開發人員額外付出努力,以確保考慮到所有所需的權限。如果您擔心惡意包和供應鏈攻擊,這個努力可能是值得的。到目前為止,我僅在概念驗證中使用了這種方法,沒有在生產環境中使用過。使用Deno這樣做并不替代代碼和依賴項掃描工具,但它可能成為一種及早發現問題的預警系統。