Lần này tôi sẽ chia sẻ với các bạn về các vấn đề bảo mật trong các mô hình ứng dụng web và có sự chuẩn bị thực tiễn để tránh gặp phải chúng. Tôi hy vọng bài viết này sẽ giúp ích cho các lập trình viên hiểu rõ hơn về một số vấn đề xuất hiện đến 80% các ứng dụng ngày nay.

Password Hasing

Rất nhiều người sử dụng thuật toán băm MD5, SHA512 để băm mật khẩu. Hãy dừng việc làm này lại, chúng đã lạc hậu rồi. Bạn có thể nghĩ chúng không phải là lựa chọn tốt nhất do mã hóa yếu, nhưng nó không phải là vấn đề chính. Lý do chính là nó “nhanh”, điều này có nghĩa trong các cuộc tấn công thì hàng triệu mật khẩu có thể được thử trên một GPU, khi đó với các thuật toán băm trên thì mật khẩu có thể được dò ra một cách nhanh chóng nhất.
Giải pháp tôi cho là khả thi nhất (không chỉ có cách này) là sử dụng BCrypt để lưu trữ mật khẩu người dùng, nó là một hàm băm thích nghi dựa trên thuật toán mã hóa khóa đối xứng Blowfish. BCrypt cũng giới thiệu một yếu tố để làm việc, giá trị xác định làm thế nào làm chậm chức năng băm. Các giá trị cao hơn sẽ cho công việc băm sẽ mất nhiều thời gian hơn và sẽ tạo ra các giá trị băm khác nhau, điều này làm cho nó an toàn với các cuộc tấn công mạnh
Bạn muốn băm mật khẩu vì ai đó truy cập cơ sở dữ liệu của ứng dụng, họ không thể khôi phục các phiên bản gốc của mật khẩu (nếu nó được băm đúng cách)
Tôi có một câu hỏi khá hay: Tại sao băm mật khẩu ở back-end mà không phải là front-end? Trong cả hai trường hợp mật khẩu được hash được lưu ở cơ sở dữ liệu có phải không?
Câu trả lời là KHÔNG!!! Nếu băm mật khẩu ở back-end, hacker phải crack lần đầu tiên (mang lại phiên bản gốc) để sử dụng chúng trên trang web của bạn, nhưng nếu băm ở front-end, hacker không cần làm điều này, họ có thể vượt qua được mã băm vì nó được lưu trong cơ sở dữ liệu.

XSS

Những người đang sử dụng jQuery hoặc Javascript sẽ chắc chắn gặp phải vấn đề này vì không có cơ chế để thực hiện XSS. Thậm chí nếu có, nó thực sự không cần thiết. Hãy cùng xem ví dụ sau

chèn thêm dữ liệu với innnerHTML có thể gây ra các vấn đề nghiêm trọng như responseText từ back-end có thể là một cái gì đó không mong muốn như sau

<img onerror=”alert(‘XSS attacked’)” src=”NotAProperUrlhere”>

và mã JavaScript của ai đó sẽ chạy trên trình duyệt của bạn. Thật vi diệu phải không😱
Giống như với các hàm jQuery html()append(). Những thẻ script khác, không chỉ có thế, còn có rất nhiều tag có thể làm việc này
Nhưng nếu sử dụng Angular, React, … bạn có thể chắc chắn rằng được bảo vệ khỏi các cuộc tấn công XSS trừ khi vô hiệu hóa các tính năng bảo mật mà không được khuyến nghị.

<div dangerouslySetInnerHTML={createMarkup()} />;

Đây là cách bạn bỏ qua quy tắc của React để ngăn chặn tấn công XSS

Session Handling

Trong hầu hết các trường hợp, sau khi bắt đầu một phiên làm việc, bạn tạo một SessionID (có thể thực hiện bằng lib) và lưu trữ nó trong cookie của trình duyệt để xử lý người dùng đã được xác thực cho mỗi lần ajax được gọi.
Luôn luôn phải cẩn thận về những điểm sau:

  1. Cookie luôn có flag “httpOnly” do đó JavaScript của kẻ tấn công không thể truy cập vào SessionID
  2. SessionID không nên là tên người dùng, id của người dùng hoặc một cái gì đó tương tự như vậy. Nó nên là một chuỗi ngẫu nhiên, duy nhất, và không đoán được. Không sự dụng Math.random() hoặc bất cứ thứ gì như thế vì nó không an toàn về mã hóa. Và để khách quan nhất, nó thậm chí không ngẫu nhiên 🙂 Bạn có thể sử dụng uuid/v5 . Nó thực sự hoạt động tốt.
  3. Một phiên không nên có thời gian dài, khi đó SessionID không còn trên bộ nhớ cache của ứng dụng web trong khoảng thời gian dài, từ nơi mà kẻ tấn công có thể có được nó
  4. Phiên nên được hủy sau khi người dùng không hoạt động.

Cảm ơn vì đã đọc bài viết! To be continued…