+2

Tìm hiểu về Web Security - Phần 1: Secrets

Mayfest2023

Web security là một chủ đề rất quan trọng trong ngành công nghệ thông tin hiện nay. Trong bài viết này, chúng ta sẽ tập trung vào việc giữ các "secret" (thông tin bí mật) an toàn trên môi trường trình duyệt web.

Environment Variables

Biến môi trường giống như các biến toàn cục trên máy chủ, chúng ta thường sử dụng để lưu trữ các thông tin bí mật. Tuy nhiên, nếu hiển thị các biến này trên mã giao diện người dùng trong trình duyệt, chúng ta sẽ không còn được coi là thông tin bí mật nữa.

Để giải quyết vấn đề này, chúng ta có thể sử dụng các package như dotenv để cấu hình các biến môi trường trong các tệp, và đảm bảo rằng chúng không được hiển thị trên giao diện người dùng.

Cách khác để sử dụng các biến môi trường là tùy chỉnh chúng cho từng môi trường khác nhau. Ví dụ, chúng ta có thể định nghĩa một biến môi trường để xác định môi trường hiện tại như

if (NODE_ENV=testing) {
  URL_BASE=http://localhost:3000
} else {
  URL_BASE=http://staging-domain.net
}

Sau đó, chúng ta có thể sử dụng điều kiện if để xác định giá trị của các biến khác nhau dựa trên môi trường hiện tại.

Tùy thuộc vào cách triển khai, chúng ta có thể tạo các dự án riêng cho từng môi trường và chỉ cần thay đổi các giá trị của các biến. Điều này giúp đảm bảo rằng các thông tin bí mật được bảo vệ và không bị lộ ra ngoài môi trường trình duyệt.

Secret Servers

Trong quá trình phát triển ứng dụng, bạn có thể cần lưu trữ các bí mật như thông tin đăng nhập hoặc khóa API. Tuy nhiên, lưu trữ các bí mật trực tiếp trong mã nguồn hoặc biến môi trường không phải là một cách an toàn để bảo vệ chúng.

Thay vào đó, bạn nên sử dụng các máy chủ bảo mật được thiết lập để lưu trữ các bí mật của mình. Các máy chủ này được tạo để chỉ chia sẻ thông tin đăng nhập và được bảo vệ bởi các tính năng xác thực, phân quyền, lưu trữ và truy xuất bí mật tích hợp.

Một trong những ví dụ về sản phẩm này là Google Cloud, cung cấp tính năng lưu trữ và quản lý bí mật tích hợp trong hệ thống của bạn để triển khai mã của mình.

Nếu bạn lưu trữ các bí mật của mình trên các máy chủ bảo mật này, bạn có thể dễ dàng quay chuyển chúng mà không cần sửa đổi mã nguồn hoặc biến môi trường.

Tokens

Các token là các chuỗi đại diện cho thông tin đã được mã hóa, thường sử dụng băm mật mã hóa, và được sử dụng để xác thực và ủy quyền. Trong phát triển ứng dụng web, chúng ta thường sử dụng các mã thông báo để xác thực và ủy quyền người dùng. Các khóa hoặc mã thông báo này thường được nhận từ các API cho phép phát triển ứng dụng của bạn.

Trong phát triển web, có nhiều thuật toán mã hóa khác nhau, nhưng JWT (JSON Web Token) là một trong những thuật toán phổ biến. JWT là một mã thông báo Web JSON với tính năng mã hóa dữ liệu dựa trên JSON. Nó được thiết kế để nhỏ gọn, an toàn với URL và dễ dàng sử dụng trong JavaScript, làm cho nó rất phù hợp cho các yêu cầu HTTP trong phát triển web. Các mã thông báo JWT được định dạng giống như các yêu cầu HTTP, bao gồm các tiêu đề, một tải trọng chứa dữ liệu JSON và một chữ ký. Chữ ký là một loại mã hóa khác, được gọi là mã ký hiệu mã. Mã ký hiệu mã được sử dụng để đảm bảo tính toàn vẹn của thông tin bằng cách xác minh nguồn gốc.

Tương tự như nhiều tiêu chuẩn mã hóa khác, các thuật toán JWT không bí mật. Người dùng có thể dán mã JWT vào trình khám phá JWT của Auth0 để xem thông tin bên trong. Đó là lý do tại sao bạn cần giữ các mã thông báo, bao gồm JWT, là bí mật và thường xuyên thay đổi chúng. Hơn nữa, chỉ nên gửi chúng qua HTTPS để đảm bảo tính bảo mật.

Các token thường được giữ trên máy chủ bảo mật, tuy nhiên trong phát triển web, chúng ta cũng cần lưu trữ thông tin về người dùng trong trình duyệt. Một ví dụ của việc lưu trữ thông tin đó là cookie.

Cookies

image.png

Khi bạn đăng nhập, máy chủ sẽ nhận được thông tin token xác thực/ủy quyền của bạn và đóng gói lại thông tin mà giao diện trước cần vào một cookie để gửi qua HTTP. Tiêu đề "set-cookie" là tiêu đề cụ thể được sử dụng để chứa các cặp khóa-giá trị, ví dụ như một đối tượng JavaScript hoặc một bộ tuple Python.

Để đảm bảo an toàn cho cookie, cần sử dụng các thuộc tính "secure", "SameSite" và "HttpOnly". Thuộc tính "secure" chỉ cho phép cookie được gửi qua HTTPS. Thuộc tính "SameSite" có chế độ "strict" sẽ ngăn chặn các yêu cầu CORS truy cập cookie, giá trị "lax" sẽ gửi cookie khi người dùng truy cập cùng nguồn, và giá trị "none" không giới hạn yêu cầu cho cookie. Thuộc tính "HttpOnly" chỉ cho phép cookie được đọc bởi yêu cầu HTTP và không thể truy cập nó bằng API cookie. Nếu không đặt "HttpOnly" và "SameSite=strict", ai cũng có thể truy cập cookie của bạn trong trình duyệt bằng JavaScript.

Khi cần lưu thông tin phiên của người dùng trong giao diện trước, không cần đặt bất kỳ điều gì bí mật nào trong cookie. Thay vào đó, giao diện trước có thể lưu trữ một token hoặc ID hết hạn, về cơ bản là một khóa công khai. Khóa công khai này có thể được biết rộng rãi mà không ảnh hưởng đến bảo mật, vì chỉ khi hai khóa được ghép lại thì thông tin nhạy cảm mới được tiết lộ. Khóa bí mật thì được lưu trữ ở phía máy chủ để xác thực.

Man-in-the-Middle

image.png

Bạn cần bảo vệ chặt chẽ token và cookie của mình để ngăn chặn các cuộc tấn công Man in the Middle. Nếu sử dụng giao thức HTTP, tin tặc có thể giả mạo thông tin giữa người gửi và người nhận. Tin tặc sẽ gửi lại thông tin đó như chưa được mở ra và thường nhắm vào các thông tin bảo mật trong cookie của bạn. Ngoài ra, họ còn quan tâm đến cách mã hóa hay ký mã thông tin của bạn.

Vì vậy, bạn cần sử dụng các phương thức mã hóa bảo mật, như HTTPS, để bảo vệ các thông tin nhạy cảm. Ngoài ra, cần sử dụng các thuộc tính an toàn nhất của cookie, bao gồm "secure", "SameSite", và "HttpOnly", để giảm thiểu nguy cơ bị tấn công.

Nếu muốn tìm hiểu thêm về cách bảo vệ cookie và token, bạn có thể tham khảo bài viết của OWASP.

Web Storage API

Nếu bạn muốn lưu trữ thông tin không bí mật trên phía front-end, Web Storage API là một lựa chọn tuyệt vời.

Web Storage API bao gồm hai phần - session storage và local storage. Session storage chỉ lưu trữ thông tin trong phiên làm việc, có nghĩa là thông tin sẽ bị xóa khi bạn đóng trình duyệt hoặc tab. Local storage không có hạn chế thời gian, thông tin lưu trữ sẽ tồn tại ngay cả khi bạn đóng trình duyệt.

Web Storage API có các phương thức tích hợp sẵn, giúp việc lưu trữ và truy cập thông tin trở nên dễ dàng hơn bao giờ hết. Ví dụ, để lưu trữ một cặp giá trị khóa trong local storage, bạn có thể sử dụng phương thức sau:

localStorage.setItem(key, value)

Còn để truy cập giá trị đã lưu trữ trong session storage, bạn có thể sử dụng phương thức sau:

sessionStorage.getItem(key)

Tuy nhiên, hãy nhớ rằng Web Storage API không được bảo mật và không nên được sử dụng để lưu trữ thông tin nhạy cảm hoặc bí mật.

IndexedDB API

IndexedDB API là một cơ sở dữ liệu đối tượng được lưu trữ trong trình duyệt của bạn. Nó cho phép bạn lưu trữ lớn hơn so với Web Storage API, và có thể lưu trữ các loại dữ liệu khác nhau, bao gồm cả hình ảnh và video.

IndexedDB API cũng có thể hoạt động ngoại tuyến, có nghĩa là dữ liệu vẫn được lưu trữ và truy cập được ngay cả khi bạn không có kết nối internet. Khi bạn kết nối lại, các thay đổi sẽ được đồng bộ hóa với máy chủ.

Để sử dụng IndexedDB API, bạn cần tạo một phiên bản cơ sở dữ liệu, sau đó tạo các bảng để lưu trữ các đối tượng. Các đối tượng được lưu trữ dưới dạng các bản ghi, và bạn có thể truy cập chúng bằng các truy vấn.

IndexedDB API cũng có thể được sử dụng để lưu trữ thông tin bí mật, nhưng bạn cần đảm bảo rằng dữ liệu của bạn được mã hóa trước khi lưu trữ để tránh lộ thông tin.

Session Hijacking

Lưu trữ thông tin bí mật trên trình duyệt có thể gây ra nhiều nguy cơ bảo mật, bao gồm cả cuộc tấn công người đứng giữa (man in the middle attack).

Kẻ tấn công có thể chiếm quyền truy cập vào thông tin phiên làm việc được lưu trữ trên trình duyệt và sử dụng nó để đánh cắp tài khoản của bạn hoặc giả mạo phiên làm việc của bạn.

Để đạt được mục đích này, kẻ tấn công có thể sử dụng các kỹ thuật như mã độc, clickjacking/UI redressing và XSS. Vì vậy, luôn giả định rằng bất cứ thông tin nào được lưu trữ trên trình duyệt đều có nguy cơ bị xâm nhập và hạn chế lưu trữ thông tin bí mật trên phía front-end.

Tổng kết

Tổng quan về bảo mật là điều quan trọng để bảo vệ thông tin riêng tư và tránh các rủi ro tiềm ẩn. Trên web, bảo mật là một chủ đề phức tạp, nhưng không có nghĩa là bạn phải dành nhiều thời gian để nắm bắt nó. Thực tế, bảo mật web có thể trở nên đơn giản hơn nếu bạn áp dụng các phương pháp và công nghệ bảo mật chính xác.

Mã hóa là một trong những giải pháp hiệu quả nhất để bảo vệ thông tin của bạn. Với các thuật toán mã hóa và việc thay đổi thường xuyên các khóa mã hóa, bạn có thể đảm bảo rằng thông tin của mình được bảo vệ tốt. Hãy luôn tập trung vào bảo mật và hiểu rõ ràng về các rủi ro tiềm ẩn để bảo vệ thông tin cá nhân của mình trên web.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.