這將是一個分爲兩部分,內容是關於在生產環境下,跑Express
應用的最佳實踐。第一部分會關注安全性,第二部分最會關注性能和可靠性。當你讀這篇文章時,假設你已經對Node.js
和web開發有所瞭解,而且對生產環境有了概念。php
生產環境,指的是軟件生命循環中的某個階段。當一個應用或API已經被它的終端用戶所使用時,它便處在了生產環境。相反的,在開發環境下,你任然在不斷得修改和測試代碼,應用也不能被外部所訪問。html
開發環境和生產環境常常有很大的配置上的和要求上的不一樣。一些在開發環境下可使用的東西,在生產環境下,它們不必定是可以被接受的。例如,在開發環境下,咱們須要詳細的錯誤日誌信息來幫助咱們debug,而在生產環境下,這則會帶來安全隱患。又好比,在開發環境下,你沒必要考慮可伸縮性和可靠性還有性能的問題,但這些在生產環境下都很是重要。node
如下是將Express
應用部署於生產環境中的一些安全性方面的最佳實踐。git
Express
版本Express
2.x 和 3.x 已經再也不被維護了。這些版本上的安全和性能問題都將不會被修復。因此不要使用它們!若是你尚未遷移至Express
4,能夠參考這份遷移指南。github
同時也保證不要使用在安全更新列表中列出的這些不可靠版本的Express
。若是你不巧使用了,請升級至穩定版,最好是最新版。web
TLS
若是你的應用須要處理或傳輸敏感數據,請使用TLS
來確保鏈接和信息的安全。這項技術會在數據被從客戶端發出前加密它。儘管Ajax
和POST
請求中發出的數據看上去並不可見,但它們的網絡環境仍能夠被嗅探和進行中間人攻擊。正則表達式
你可能已經對SSL
加密有所瞭解。TLS
是進化版的SSL
。換句話說,若是你正在使用SSL
,請更新成使用TLS
。大多數狀況下,咱們推薦使用Nginx
來處理TLS
。關於如何在Nginx
(或其餘服務器)上配置TLS
,請參考推薦的服務器配置(Mozilla Wiki)。sql
另外,有一個能夠很方便地取得TLS
證書的工具是Let’s Encrypt。它是一個免費的,自動化的,開放的CA
。由ISRG
提供。數據庫
Helmet
Helmet
經過適當地設置一些HTTP頭,來幫助你的應用免受一些廣爲人知的web攻擊。express
Helmet
其實就是九個設置與安全相關的HTTP頭的中間件的集合:
csp 設置了Content-Security-Policy
頭來幫助抵擋跨站腳本攻擊和其餘跨站注入。
hidePoweredBy 移除了X-Powered-By
頭。
hpkp 添加了Public Key Pinning頭來抵擋使用僞造證書的中間人攻擊。
hsts 設置了Strict-Transport-Security
頭來強制使用安全鏈接。
ieNoOpen 爲IE8+設置了X-Download-Options
頭。
noCache 設置了Cache-Control
和Pragma
頭來禁止客戶端緩存。
noSniff 設置了X-Content-Type-Options
頭來阻止瀏覽器進行MIME嗅探。
frameguard 設置了X-Frame-Options
頭來提供對點擊劫持的保護。
xssFilter 設置了X-XSS-Protection
頭來啓用大多數現代瀏覽器中的XSS過濾器。
安裝Helmet
的過程和其餘模塊沒有什麼兩樣:
$ npm install --save helmet
而後像其餘中間件同樣使用它:
... var helmet = require('helmet'); app.use(helmet()); ...
X-Powered-By
頭若是你不想使用Helmet
,那麼你至少須要禁用X-Powered-By
頭。攻擊者能夠利用這個頭(默認被啓用)來了解到你的應用是一個Express
應用,而後進行有針對性的攻擊。
因此,最佳實踐是使用app.disable()
關閉這個頭:
app.disable('x-powered-by');
若是你使用了Helmet
,則它會幫你完成這件事。
確保不要讓cookies暴露了你應用的信息。不要使用默認的session cookie
名,而且要配置好cookie的安全選項。
Express
中有兩個主要的cookie session
中間件模塊:
express-session 代替了Express 3.x中內建的express.session
中間件。
cookie-session 代替了Express 3.x中內建的express.cookieSession
中間件。
這兩個模塊的主要區別是它們存儲cookie session
的方式。express-session
在服務端存儲session
信息。它只在cookie中存儲session ID
,而不是session數據。默認狀況下,它使用內存存儲,在生產環境下,你須要本身配置可伸縮的session-store
。如下是一個session-store
的列表。
相反地,cookie-session
中間件則把數據都存儲在了cookie中:它將整個session序列化至cookie,而不只僅是一個session ID
。請僅僅在session數據很小且被早早得加密過期才使用它。瀏覽器支持的每一個cookie的大小一般最可能是4093B。因此請確保不要超過它。另外,cookie中的數據時能夠被客戶端看見的。因此若是你須要對其中的數據進行保密,使用express-session
將是一個更好的選擇。
session cookie
名這點和禁用X-Powered-By
頭是相似的。潛在的攻擊者能夠經過它們進行鍼對性的攻擊。
因此請使用比較廣泛的cookie名;如:
var session = require('express-session'); app.set('trust proxy', 1) // trust first proxy app.use( session({ secret : 's3Cur3', name : 'sessionId', }) );
經過配置如下的cookie選項來增強安全性:
secure – 確保瀏覽器使用HTTPS發送cookie。
httpOnly – 確保cookie僅經過HTTP(S)被髮送,而不是客戶端的JavaScript
。用來幫助抵禦跨站腳本攻擊。
domain – 指定cookie的域。使用它來與將要發送cookie的URL做比較。只有比較結果經過,纔會繼續檢查下面的path
屬性。
path – 指定cookie的路徑。使用它來比較請求的路徑。若是比較結果經過,纔會發送cookie。
expires – 爲持久化的cookie設置過時時間。
如下是一個使用cookie-session
中間件的例子:
var session = require('cookie-session'); var express = require('express'); var app = express(); var expiryDate = new Date( Date.now() + 60 * 60 * 1000 ); // 1 hour app.use(session({ name: 'session', keys: ['key1', 'key2'], cookie: { secure: true, httpOnly: true, domain: 'example.com', path: 'foo/bar', expires: expiryDate } }) );
使用npm
來管理你應用的依賴是強大而方便的。可是你的依賴庫若是有安全隱患,這也會影響到你的應用。你的應用只會和其最虛弱的那部分同樣的健壯。
幸運的是,有兩個工具能夠幫助你檢查第三方庫的安全性:nsp和requireSafe。這兩個工具大體上幹了相同的事情,因此選其一使用便好。
nsp
是一個用來檢查你應用的依賴庫與它的Node Security Project
數據庫中的存儲的漏洞相對比的命令行工具,你能夠經過如下方式安裝它:
$ npm i nsp -g
而後使用如下命令來進行檢查你應用的npm-shrinkwrap.json
和package.json
:
$ cd your-app $ nap check
使用requireSafe
的過程也是相似的:
$ npm install -g requiresafe $ cd your-app $ require safe check
如下是一些從Node.js安全清單中提出安全建議。詳細的建議請自行參閱它:
對應用實現一個訪問頻率限制機制來抵禦暴力破解。你可使用如express-limiter這樣的中間件。
使用csurf中間件來抵擋跨站請求僞造(CSRF)。
老是檢查和過濾用戶的輸入,來防止XSS和命令注入。
經過使用參數化的查詢(parameterized queries)或預處理語句(prepared statements),來抵擋SQL注入攻擊。
使用開源的sqlmap工具來偵測你的應用中可能被SQL注入的地方。
使用safe-regex來確保你的正則表達式的健壯性。
除了Node Security Project
代替你檢查出的Express
或其餘模塊的漏洞外。Express
應用也是一個web應用,因此你也要關注其餘相關的已知的web漏洞,而且避免它們。
原文連接:https://strongloop.com/strongblog/best-practices-for-express-in-production-part-one-security/