Giới thiệu về các cuộc tấn công giả mạo yêu cầu chéo trang (CSRF)
Cross-Site Request Forgery (CSRF) là một lỗ hổng bảo mật cho phép kẻ tấn công lừa người dùng thực hiện các hành động không mong muốn trên ứng dụng web mà không có sự đồng ý của họ. Trong một cuộc tấn công CSRF, trình duyệt của người dùng được sử dụng làm đường dẫn cho các yêu cầu trái phép đến một ứng dụng dễ bị tổn thương, khai thác hiệu quả phiên xác thực của người dùng.
Tầm quan trọng của việc bảo vệ chống lại các cuộc tấn công CSRF
Nếu một ứng dụng web không được bảo vệ trước các cuộc tấn công CSRF, nó có thể dẫn đến những hậu quả nghiêm trọng, bao gồm:
- Sửa đổi hoặc xóa dữ liệu trái phép
- Truy cập tài khoản trái phép hoặc thay đổi mật khẩu
- Giao dịch tài chính trái phép
Để giữ an toàn cho các ứng dụng Node Express của bạn, điều cần thiết là phải triển khai các biện pháp bảo vệ CSRF thích hợp.
Triển khai Bảo vệ CSRF trong Express
Trong bài viết này, chúng tôi sẽ hướng dẫn quy trình triển khai bảo vệ CSRF cho ứng dụng web Node Express, sử dụng các bước sau:
- Cài đặt các gói cần thiết
- Thiết lập phần mềm trung gian
- Tạo mã thông báo CSRF
- Xác thực mã thông báo CSRF
- Xử lý lỗi mã thông báo
Bước 1: Cài đặt các gói cần thiết
Trước tiên, bạn sẽ cần cài đặt hai gói để giúp triển khai bảo vệ CSRF: csurf
và cookie-parser
. Để thực hiện việc này, hãy chạy lệnh sau trong thiết bị đầu cuối của bạn:
1 2 | <span class="token function">npm</span> <span class="token function">install</span> csurf cookie-parser |
Bước 2: Thiết lập Middleware
Sau khi cài đặt các gói, bạn sẽ cần thiết lập phần mềm trung gian trong ứng dụng Express.js của mình. Nhập các gói cookie-parser
và csurf
và thêm chúng vào ngăn xếp phần mềm trung gian của bạn:
1 2 3 4 5 6 7 8 9 | <span class="token keyword">const</span> express <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'express'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> cookieParser <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'cookie-parser'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> csrf <span class="token operator">=</span> <span class="token function">require</span> <span class="token punctuation">(</span> <span class="token string">'csurf'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">const</span> app <span class="token operator">=</span> <span class="token function">express</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> app <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> <span class="token function">cookieParser</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> app <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> <span class="token function">csrf</span> <span class="token punctuation">(</span> <span class="token punctuation">{</span> cookie <span class="token operator">:</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Bước 3: Tạo mã thông báo CSRF
Tiếp theo, bạn cần tạo mã thông báo CSRF cho mỗi phiên người dùng. Để thực hiện việc này, hãy bao gồm chức năng csrfToken
trong trình xử lý tuyến đường của bạn:
1 2 3 4 5 | app <span class="token punctuation">.</span> <span class="token function">get</span> <span class="token punctuation">(</span> <span class="token string">'/form'</span> <span class="token punctuation">,</span> <span class="token punctuation">(</span> <span class="token parameter">req <span class="token punctuation">,</span> res</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">const</span> csrfToken <span class="token operator">=</span> req <span class="token punctuation">.</span> <span class="token function">csrfToken</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> res <span class="token punctuation">.</span> <span class="token function">render</span> <span class="token punctuation">(</span> <span class="token string">'form'</span> <span class="token punctuation">,</span> <span class="token punctuation">{</span> csrfToken <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Bao gồm mã thông báo CSRF được tạo dưới dạng trường ẩn trong biểu mẫu HTML của bạn:
1 2 3 4 5 6 | <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> form</span> <span class="token attr-name">action</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> /submit <span class="token punctuation">"</span></span> <span class="token attr-name">method</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> POST <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> input</span> <span class="token attr-name">type</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> hidden <span class="token punctuation">"</span></span> <span class="token attr-name">name</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> _csrf <span class="token punctuation">"</span></span> <span class="token attr-name">value</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> {{csrfToken}} <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> <span class="token comment"><!-- other form fields go here --></span> <span class="token tag"><span class="token tag"><span class="token punctuation"><</span> button</span> <span class="token attr-name">type</span> <span class="token attr-value"><span class="token punctuation attr-equals">=</span> <span class="token punctuation">"</span> submit <span class="token punctuation">"</span></span> <span class="token punctuation">></span></span> Submit <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> button</span> <span class="token punctuation">></span></span> <span class="token tag"><span class="token tag"><span class="token punctuation"></</span> form</span> <span class="token punctuation">></span></span> |
Bước 4: Xác thực Mã thông báo CSRF
Phần mềm trung gian csurf
tự động xác thực mã thông báo CSRF trong các yêu cầu POST đến. Nếu mã thông báo hợp lệ, yêu cầu sẽ tiếp tục như bình thường. Nếu mã thông báo bị thiếu hoặc không chính xác, sẽ xảy ra lỗi.
Bước 5: Xử lý lỗi mã thông báo
Để xử lý lỗi mã thông báo CSRF một cách hiệu quả, bạn có thể thêm trình xử lý lỗi tùy chỉnh vào ứng dụng Express.js của mình:
1 2 3 4 5 6 7 8 9 10 | app <span class="token punctuation">.</span> <span class="token function">use</span> <span class="token punctuation">(</span> <span class="token punctuation">(</span> <span class="token parameter">err <span class="token punctuation">,</span> req <span class="token punctuation">,</span> res <span class="token punctuation">,</span> next</span> <span class="token punctuation">)</span> <span class="token operator">=></span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token punctuation">(</span> err <span class="token punctuation">.</span> code <span class="token operator">===</span> <span class="token string">'EBADCSRFTOKEN'</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// CSRF token validation failed</span> res <span class="token punctuation">.</span> <span class="token function">status</span> <span class="token punctuation">(</span> <span class="token number">403</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">send</span> <span class="token punctuation">(</span> <span class="token string">'Invalid CSRF token.'</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token comment">// Pass the error to the next middleware</span> <span class="token function">next</span> <span class="token punctuation">(</span> err <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> |
Thao tác này sẽ phát hiện lỗi mã thông báo CSRF và trả về phản hồi 403 Forbidden kèm theo thông báo hữu ích.
Phần kết luận
Bằng cách làm theo các bước này, bạn có thể bảo vệ hiệu quả các ứng dụng web Nodejs Express của mình khỏi các cuộc tấn công giả mạo yêu cầu trên nhiều trang web. Hãy nhớ cập nhật các gói của bạn và theo dõi bảo mật ứng dụng của bạn thường xuyên để đảm bảo rằng nó vẫn an toàn trước các lỗ hổng.
Và cuối cùng
Như mọi khi, tôi hy vọng bạn thích bài viết này và có một cái gì đó mới. Xin cảm ơn và hẹn gặp lại các bạn trong những bài viết tiếp theo!
Nếu các bạn thích bài viết này thì hãy cho mình 1 like và subscribe để ủng hộ mình nhé. Cảm ơn.