各框架對策
Express(Node.js)的資安對策 — 正式環境強化實務參考
安全維運 Express(Node.js)的實務參考。因為最小主義,防禦要自己補上——helmet 標頭、npm 的 CVE、輸入驗證、授權、速率限制、工作階段/CSRF、SSRF。不含攻擊步驟,只講防禦與點檢。
對象:正在 Express(Node.js)上維運 API 或應用程式的人。這裡不談攻擊步驟,而是把要替最小框架補上的防禦,整理成正式環境向的實務參考(附優先度的檢查表、分領域對策、自我檢驗)。想看跨框架的全貌,請參閱 各框架資安對策的入口。
附優先度的強化檢查表
先由上而下實施這張表。P0 是前提,P1 是最頻繁的事故源,P2 是持續性的維運衛生。
P0 ── 前提(先做這個)
標頭(helmet)+停用 x-powered-by/npm 相依套件 CVE 監控/機密從 env、不暴露堆疊
P1 ── 最頻繁的事故源
輸入驗證與注入防護/擁有者範圍的授權
P2 ── 維運衛生
速率限制與大小上限/工作階段、cookie、CSRF/SSRF
| 優先 | 對策 | 具體(Express) |
|---|---|---|
| P0 | 安全性標頭 | helmet 式:CSP/HSTS/X-Content-Type 等。停用 x-powered-by |
| P0 | npm 相依套件 CVE | 用 npm audit/osv-scanner 監控;以實際執行版本判定、迅速修補 |
| P0 | 機密與錯誤 | 機密從環境變數取得。正式環境不對外暴露堆疊追蹤 |
| P1 | 輸入驗證 | 驗證/淨化輸入(型別/範圍/允許值)。主體大小上限 |
| P1 | 注入 | DB 查詢綁定。注意 NoSQL 運算子注入($)。別把輸入傳給 eval |
| P1 | 授權 | 驗證+在每條路由做擁有者範圍的授權。JWT:驗證簽章、固定 alg |
| P2 | 速率限制 | 對登入/API 設嘗試/流量上限。抑制暴力破解、濫用、DoS |
| P2 | 工作階段/cookie | secure/httpOnly/sameSite。CSRF(cookie 工作階段)。正式環境工作階段儲存 |
| P2 | SSRF | 伺服器端抓取採允許清單+封鎖內部 IP/中繼資料 |
1. 安全性標頭與削減暴露(P0)
Express **預設不會設定安全性標頭。**先把這個底線墊高。
- 用 helmet 式中介層加上 CSP、HSTS、X-Content-Type-Options、frameguard 等。
- 停用
x-powered-by以減少框架/版本的暴露。 - 用 安全性標頭檢測 檢查自己的站台。
2. 相依套件(npm)與供應鏈(P0)
- 用
npm audit或 osv-scanner 對相依套件的 CVE 做機器監控,以實際執行版本判定、迅速修補(→ 監控相依套件的 CVE)。 - Node 的相依套件樹龐大,且有供應鏈風險(typosquatting、
postinstall鉤子)。安裝時要審視,並把數量壓下來。 - 讓 Node 保持在受支援的(LTS)版本,別放任 EOL 版本。
3. 輸入驗證與注入(P1)
- 驗證/淨化所有輸入(body、query、params、headers)。設定主體大小上限以抑制 DoS。
- SQL:用佔位符綁定;絕不用字串串接來組查詢(→ 什麼是 SQL 注入)。
- NoSQL:留意經由物件型輸入的運算子注入(
$)(別把原始物件傳進查詢)。 - 別把外部輸入傳給
eval這類危險的求值。
4. 驗證與授權(P1)
常見(危險)
- 沒有授權——「登入=允許」
- 只依賴中介層的順序/存在
- 原封不動地信任用戶端提供的 ID/旗標
- JWT 簽章未驗證/允許
alg:none
正確
- 驗證之外,還在每條路由做擁有者範圍的授權
- 在靠近資料的地方驗證(別依賴順序)
- 在伺服器端再次驗證(抵抗 ID 掉包)
- JWT 驗證簽章+固定 alg(拒絕
alg:none)
參閱 什麼是 IDOR · 什麼是 JWT。你可以自己檢視 JWT 的內容(JWT 解碼器)。
5. 速率限制與濫用防護(P2)
- 對登入、API、密碼重設套用嘗試/流量上限,抑制暴力破解、濫用與 DoS。
- 對請求主體與上傳設定大小上限(防止大型負載造成資源耗盡)。
6. 工作階段與 cookie(P2)
- 在工作階段 cookie 上設定
secure/httpOnly/sameSite。 - 對 cookie 工作階段的應用程式,加上 CSRF 保護(→ 什麼是 CSRF)。
- 正式環境使用適當的工作階段儲存(預設的記憶體內儲存不適用於正式環境)。在登入時重新產生工作階段。
7. SSRF 與伺服器端抓取(P2)
- 伺服器端抓取使用者提供的 URL 時,應把目標限定在允許清單,並在連線時封鎖對內部 IP/雲端中繼資料的觸達(→ 什麼是 SSRF)。
8. 錯誤處理與正式環境設定(P0〜P2)
- 使用集中式錯誤處理器,並不對外暴露堆疊追蹤。
- 以
NODE_ENV=production執行。在代理之後,正確設定trust proxy,讓 scheme 與用戶端 IP 不被誤判。 - 確實在終端做 TLS/HTTPS。
檢驗:你的 Express 真的強化了嗎
建好不是結束——點檢過才算完成。以下是針對你自己環境的防禦性自我檢查。
標頭與暴露
x-powered-by 已消失。錯誤不會洩漏內部
授權有效
相依套件、速率限制、SSRF
npm audit/osv 是乾淨的、登入速率限制有效,且對外抓取無法觸達內部 IP。本站的觀點:最小框架把自由與責任成套
Express 的魅力在於輕巧與自由——那意味著防禦也由你來設計。Rails 與 Laravel 預設會替你守的部分(標頭、CSRF、授權的骨架),在 Express 上要刻意接進去。重心是把上面的表由上而下逐一處理——設定標頭、驗證輸入、在公開入口寫上授權,並對相依套件監控 CVE。尤其 Node 的相依套件數量龐大,所以相依套件的鮮度決定事故的成敗。丟掉「框架會替我守」的假設,把防禦明確地補上去。
接下來讀
- 入口:各框架資安對策 · Next.js 資安對策(同為 Node)
- 實務:監控相依套件的 CVE · 漏洞應變實務
- 名詞:什麼是 IDOR · 什麼是 SSRF · 什麼是 JWT · 什麼是 CSRF
- 工具:安全性標頭檢測 · JWT 解碼器
FAQ
Q要保護 Express,第一步該做什麼?
優先度 P0 的三件事:(1)用 helmet 式的中介層加上安全性標頭(CSP/HSTS 等)並停用 x-powered-by;(2)對 npm 相依套件的 CVE 做機器監控並迅速修補,以實際執行版本判定;(3)從環境讀取機密,正式環境不對外暴露堆疊追蹤。Express 預設不會替你守住這些,所以補上去是底線。接著再進到輸入驗證、授權與速率限制。
Q需要像 helmet 那樣的安全性標頭嗎?
需要。Express 預設不會設定資安相關的 HTTP 標頭。請用 helmet 式的中介層加上 CSP、HSTS、X-Content-Type-Options 等,降低點擊劫持、MIME 探測等基本風險。也要停用 x-powered-by 以減少框架的暴露。光是加上去就能墊高底線,所以最先放進去。
Q驗證與授權要怎麼組?
在驗證中介層確認登入之後,務必在每條路由寫上擁有者範圍的授權——確認目標確實屬於該使用者。別依賴中介層的順序或它單純存在;要在靠近資料的地方驗證。若使用 JWT,要求驗證簽章並固定 alg(拒絕 alg:none)。
Qnpm 相依套件的漏洞要怎麼管理?
用 npm audit 或 osv-scanner 對已知 CVE 做機器監控並迅速修補,以實際執行版本判定。Node 的相依套件樹非常龐大,且有供應鏈風險(typosquatting、postinstall 鉤子),所以相依套件的鮮度與安裝時的審視才是勝負關鍵。也要讓 Node 保持在受支援的(LTS)版本。
Q最起碼要做什麼?
(1)helmet 式標頭+停用 x-powered-by;(2)驗證/淨化所有輸入;(3)擁有者範圍的授權;(4)對登入/API 加速率限制+主體大小上限;(5)npm 相依套件 CVE 監控+迅速修補;(6)正式環境不對外暴露堆疊追蹤。這組最小集合就能補起最小框架的大半破口。