Express.js Best Security Paractices
Bài đăng này đã không được cập nhật trong 6 năm
Express.js là một trong những framework phổ biến nhất trong làng dev Node.js, nó là một framework đơn giản nhưng đủ mạnh để giúp chúng ta tiếp cận cũng như phát triển website dựa trên framwork này. Cũng giống như với các framework khác, với Express.js chúng ta cũng có khá nhiều điểm cần lưu ý để đảm bảo ứng dụng của mình hoạt động linh hoạt và an toàn trên môi trường production. Thuật ngữ "production" được dùng để chỉ định giai đoạn trong vòng đời phát triển phần mềm mà khi đó ứng dụng hoặc api đã được public đến người dùng cuối hoặc khách hàng. Ngược lại, giao đoan "development" là giai đoạn khi mà chúng ta vẫn còn đang tiếp tục công việc coding hoặc testing. Hai môi trường Production và Development thường có những cài đặt, cấu hình khác nhau nhằm phục vụ cho việc debug, testing khi development và đảm bảo performance, security khi lên production; trong đó thì có rất nhiều thứ hợp lý và hữu ích khi development nhưng lại hoàn toàn không nên hoặc bị cấm khi lên production (như là logging, debugging...) Dưới đây là một số lưu ý khi triển khai production cho một ứng dụng Express.js
Không sử dụng những phiên bản có lỗi hoặc không được khuyến khích (deprecated)
Phiên bản mới nhất (hiện tại) của Express.js là 4.16.1, với rất nhiều tính năng cải tiến về tốc độ cũng như bảo mật; các phiên bản tiền nhiệm như Express 2.x hoặc Express 3.x cũng rất mạnh mẽ và được đánh giá cao, tuy nhiên các phiên bản cũ này đã không còn được hỗ trợ nữa. Điều đó có nghĩa là tất cả những vấn đề về hiệu năng hay bảo mật của Express 2.x và Express 3.x sẽ không còn được khắc phục nữa. Vậy nên nếu bạn đang làm một ứng dụng mới sử dụng Express.js thì hãy nên sử dụng phiên bản mới nhất; nếu bạn vẫn đang sử dụng Express.js cũ cho các ứng dụng của mình thì nên xem xét cập nhật lên Express 4 nếu có thể. Ngoài ra thì để đảm bảo phiên bản mình sử dụng không phải là phiên bản lỗi thì bạn cũng có thể kiểm tra danh sách các phiên bản có lỗi tại đây
Sử dụng Transport Layer Security (TLS)
Nếu ứng dụng của bạn có làm việc với những dữ liệu quan trọng, hãy sử dụng Transport Layer Security (TLS) để bảo mật các kết nối và dữ liệu của mình. Công nghệ này sẽ mã hóa dữ liệu trước khi nó được gửi đi từ client lên server, điều này sẽ giúp ngăn chặn một số kỹ thuật hacking phổ biến. Mặc dù với Ajax và Post requets thì có vẻ như dữ liệu truyền đi đã bị che dấu (chúng ta không nhìn thấy nó như với GET request), tuy nhiên thì trong thực tế chúng vẫn có thể bị tấn công bởi các công cụ hỗ trợ packet sniffing hoặc tấn công man-in-the-middle Mã hóa Secure Socket Layer (SSL) được sử dụng rất phổ biến và chắc hẳn bạn đã gặp nó rất nhiều rồi. TLS đơn giản chỉ là quá trình tiền theo của SSL. Nói theo một cách khác thì nếu bạn đã sử dụng SSL trước đó thì hãy nên xem xét để nâng cấp lên TLS, TLS có thể được cài đặt rất dễ dàng thông qua Nginx. Bạn có thể tìm hiểu về cấu hình TLS với Nginx tại đây Ngoài ra thì bạn nên thử Let's Encrypt, đó là một công cụ miễn phí, tự động hoàn toàn với chứng chỉ xác thực được cung cấp bởi Internet Security Research Group (ISRG)
Sử dụng Helmet
Helmet là một package được viêt để giúp bạn bảo vệ ứng dụng của mình khỏi những lỗ hổng đã biết bằng cách thiết lập các Http headers một cách phù hợp Thực tế thì Helmet chỉ là một tập hợp các Middleware nhỏ làm nhiệm vụ thiết lập các Http headers liên quan đến bảo mật, cụ thể như sau:
- csp Thiết lập header
Content-Security-Policy
giúp ngăn chặn tấn công cross-site scripting và các tấn công cross-site injections khác. - hidePoweredBy Xóa header
X-Powered-By header
khỏi response, giúp dấu đi thông tin mã nguồn bạn sử dụng. - hpkp Thêm header
Public Key Pinning
giúp bản vệ ứng dụng khỏi tấn côngman-in-the-middle
với chứng chỉ giả mạo. - hsts Cài đặt header
Strict-Transport-Security
giúp thực thi kết nối bảo mật (HTTP over SSL/TLS) đến server. - ieNoOpen set header
X-Download-Options
cho IE8+. - noCache set header
Cache-Control
vàPragma
để tắt client-side caching. - noSniff set header
X-Content-Type-Options
giúp ngăn chặn trình duyệt khỏi MIME-sniffing. - frameguard set header
X-Frame-Options
để bảo vệ ứng dụng khỏiclickjacking
. - xssFilter set header
X-XSS-Protection
giúp kích hoạt bộ lọcCross-site scripting (XSS)
.
Cài đặt và sử dụng Helmet
npm install --save helmet
var helmet = require('helmet')
app.use(helmet())
Nếu bạn không muốn sử dụng Helmet thì tốt nhất vẫn nên tắt header X-Powered-By
. Hacker có thể sử dụng header này để xác định ứng dụng của bạn sử dụng Express.js
app.disable('x-powered-by')
Lưu ý rằng tắt header
x-powered-by
không đảm bảo chắc chắn được hacker không thể xác định app của bạn viết trên Express.js, tuy nhiên nó là cách khá đơn giản và cũng có hiệu quả rất tốt
Bảo mật với cookie
Để đảm bảo rẳng cookies không khiến ứng dụng của bạn bị hack, tuyệt đối không sử dụng cookie name mặc định cũng như cần phải thiết lập đúng cách các options với cookie Đối với việc bảo mật cookies, chúng ta có thể sử dụng 2 packages sau:
- express-session thay thế middleware mặc định
express.session
lên phiên bản Express 3.x. - cookie-session thay thế middleware mặc định
express.cookieSession
lên phiên bản Express 3.x. Điểm khác biệt chính giữa hai packages này nằm ở cách chúng lưu trữ dữ liệu cookie session.express-session
lưu trữ dữ liệu session tại server, nó chỉ sử dụng cookie để lữu trữ Session ID. Mặc định nó sẽ sử dụng bộ lưu trữ in-memory và cách lưu trữ này không được thiết kế để chạy với môi trường production. Với môi trường Production, bạn sẽ cần phải cài đặt một bộ lưu trữ session có tính linh hoạt cao và có khả năng mở rộng, xem danh sách được hỗ trợ: https://github.com/expressjs/session#compatible-session-storescookie-session
thì ngược lại, nó triển khai một bộ lưu trữcookie-backed
:cookie-session
sẽ serializes toàn bộ dữ liệu session thành cookie. Chỉ sử dụng cách này khi dữ liệu session nhỏ và có thể dễ dàng để mã hóa. Mặc dù browser có thể hỗ trợ tối thiểu 4096 bytes cho mỗi cookie nhưng để đảm bảo bạn không bị quá giới hạn này thì tốt nhất không để cho size vượt quá 4093 bytes với mỗi cookie domain. Bạn cũng nên lưu ý rằng dữ liệu cookie là mở và có thể can thiệp bởi client, do đó trong trường hợp dữ liệu cookie là quan trọng thì tốt hơn nên sử dụngexpress-session
.
Không sử dụng cookie name mặc định
Cũng giống như với việc dấu đi header X-Powered-By
, chúng ta cũng nên thay đổi tên mặc định của cookie, điều này sẽ giúp ẩn dấu thông tin framework ta sử dụng
var session = require('express-session')
app.set('trust proxy', 1) // trust first proxy
app.use(session({
secret: 's3Cur3',
name: 'sessionId'
}))
Thiết lập các options nâng cao bảo mật
Cài đặt các options sau đây để giúp tăng cường bảo mật cho cookie:
- secure - Đảm bảo rằng browser sẽ chỉ gửi cookie qua HTTPS.
- httpOnly - Đảm bảo rằng cookie chỉ được gửi qua HTTP(S), không phải thông qua client JavaScript, giúp ngăn chặn tấn công cross-site scripting.
- domain - Chỉ định domain của cookie; Cookie chỉ hợp lệ đối với domain phát sinh request.
- path - Chỉ định path của cookie.
- expires - Thiết lập thời gian hết hạn cho cookie. Ví dụ về thiết lập bảo mật cho cookie
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
}
}))
Cập nhật tất cả các packages hiện tại
NPM là một công cụ rất mạnh mẽ hỗ trợ quản lý các dependencies của ứng dụng, tuy nhiên các packages có thể tồn tại các lỗ hổng bảo mật có thể ảnh hưởng đến ứng dụng của bạn. Ứng dụng của bạn không thể đảm bảo được bảo mật nếu một trong các packages có lỗ hổng. Sử dụng các packages sau để kiểm tra bảo mật các packages bạn sử dụng:
Use either or both of the following two tools to help ensure the security of third-party packages that you use: nsp and Snyk.
nsp là một công cụ command-line giúp kiểm tra bảo mật dựa trên db các lỗ hổng đã biết.
$ npm i nsp -g
nsp check
Snyk cung cấp cả cli và Github integration để có thể check lỗ hổng nhanh và toàn diện hơn
$ npm install -g snyk
$ cd your-app
snyk test
snyk wizard
Tránh các lỗ hổng đã biết khác
Dưới đây là một số gợi ý bạn nên tham khảo để tăng cường bảo mật cho website của mình (đọc full tại đây https://blog.risingstack.com/node-js-security-checklist/)
- Triển khai
rate-limiting
để ngăn chặn tấn công DDOS - Sử dụng
csurf middleware
để ngăn chặn (CSRF). - Luôn lọc và tiền xử lý user input để ngăn chặn tấn công cross-site scripting (XSS) và command injection.
- Sử dụng parameterized queries hoặc prepared statements để ngăn chặn SQL injection.
- Sử dụng sqlmap để chẩn đoán trước lỗi SQL injection vulnerabilities.
- Sử dụng nmap and sslyze để test cài đặt SSL ciphers, keys...
- Sử dụng
safe-regex
để đảm bảo tất cả cácregular expressions
không bị ảnh hưởng bởi regular expression denial of service
Tham khảo: https://www.owasp.org/index.php/Regular_expression_Denial_of_Service_-_ReDoS https://blog.risingstack.com/node-js-security-checklist/ https://letsencrypt.org/isrg/ https://wiki.mozilla.org/Security/Server_Side_TLS#Recommended_Server_Configurations https://expressjs.com/en/advanced/best-practice-security.html https://msdn.microsoft.com/en-us/library/windows/desktop/aa380515(v=vs.85).aspx
All rights reserved