API là cách thức giao tiếp phổ biến giữa BE và FE, thông tin được truyền và nhận thông qua API nên yếu tố bảo mật API cũng là một phần quan trọng trong quá trình triển khai và xây dựng API. Để tăng độ an toàn, tính bảo mật hơn mình xin giới thiệu một số biện pháp, được mình tham khảo và kết hợp với kinh nghiệm cá nhân trong quá trình làm việc.
1. Authentication
Xác thực là một biện pháp bảo mật quan trọng nhất được nghĩ đến khi muốn bảo vệ tài nguyên của hệ thống. Trước khi cung cấp dữ liệu hay cho phép người dùng thực hiện hành động nên xác thực danh tính. Có một vài cơ chế xác thực phổ biến OAuth, JWT, API keys, .... Đối với các tài nguyên không cần xác thực hay public nên được xem xét kỹ trước khi đưa ra quyết định bỏ xác thực cho các API đó không và kèm theo các biện pháp bảo vệ khác để tránh các vụ tấn công DDos. Một số tip nâng cao tính an toàn hơn trong khi triển khai các cơ chế xác thực trên:
- Sử dụng refresh token trong JWT, với access token ngắn hạn, có thể để thời gian hết hạn của token bằng một số ngẫu nhiên trong phạm vi cho phép, ví dụ access token hết hạn trong 30 phút chúng ta có thể lấy thời gian hết hạn trong khoảng 25-30 phút hoặc phạm vi lớn hơn, đều này sẽ làm tăng độ khó khi hacker muốn đoán thời gian hết hạn của access token hoặc các ứng dụng khác muốn biến API của chúng ta thành bên thứ 3 mà chưa được cấp phép hoặc trả phí.
- Thu hồi hoặc vô hiệu hoá các token đã cấp nhưng không còn dùng tới nữa, tuỳ thuộc vào hệ thống để có chiến lược triển khai hợp lý.
- Triển khai xác thực Two-Factor, Multi-Factor, có thể triển khai thêm tracking device, ip và giới hạn số người dùng có thể hoạt động cùng một lúc.
- Yêu cầu người dùng đổi mật khẩu sau một khoản thời gian nhất định, thường hay thấy ở các ứng dụng smart banking của ngân hàng.
2. Authorization
Sau khi vượt qua được bước xác thực, người dùng được quyền thực hiện các hành động lên tài nguyên hệ thống. Để bảo vệ tài nguyên và điều hướng hành động của người dùng tác động lên tài nguyên, chúng ta cần triển khai thêm cơ chế uỷ quyền hay phân quyền cho người dùng. Các hệ thống với nhiều chức năng, cần được được phân quyền để đảm bảo các hành động thực thi của người dùng là hợp pháp và cho phép thực hiện, thường sẽ bắt đầu chia role như: user, admin,.. sau đó kết các permission đi kèm lên từng resouce như cho phép read, write, delete, update, ... Một số hệ thống lớn, thường hay sử dụng các mô hình sau để triển khai:
- RBAC – Role-based access control
- ABAC – Attribute based access control Hai mô hình trên giống như bản nâng cấp từ role và permission nhưng có phép tuỳ biến nhiều hơn, dễ chỉnh sửa tuỳ thuộc vào đích của người cấp quyền hơn. Tất nhiên mô hình hay phương pháp nào cũng có điểm lợi và hại của nó nên cần cân nhắc hệ thống hiện tại để áp dụng cho thích hợp.
3. Validate Input
Kiểm tra và xử lý dữ liệu đầu vào, các API thường rất hay nhận các dữ liệu đầu vào thông qua query params, path variables, request body, ... hoặc dạng data file mà người dùng upload lên. Tất cả dạng dữ liệu đầu vào này nên được kiểm tra kỹ lưỡng để hạn chế một số vấn đề sau:
- Tránh nhận và lưu trữ data rác gây ảnh hưởng đến cấu trúc data của hệ thống.
- Hacker có thể lợi dụng để triển khai một số thủ thuật như: SQL injection, cross-site scripting, ... tiềm ẩn trong data và file dữ liệu.
- Hạn chế lỗi: kiểm tra khắc khe và làm sạch dữ liệu giúp cho mọi thứ hoạt động tốt hơn và ngăn chặn ngay ở bước kiểm tra dữ liệu, nếu là người triển khai API (Backend developer) thì luôn đảm bảo dữ liệu được kiểm tra ngay cả khi phía FE đã thực hiện điều đó.
- Giảm những xử lý không cần thiết, ví dụ như chỉ với việc kiểm tra id dạng uuid thông qua regex có thể giảm số lần query xuống database tìm kiếm nếu id đó chưa hợp lệ.
- Tiết kiệm tài nguyên của server: người dùng cố tình gửi một object với kích thước lớn lên server nếu không làm sạch và lọc các trường cần thiết và cứ để object lớn được lưu trữ trên RAM sẽ làm tốn tài nguyên server, điều này cũng tương tự với file làm tốn tài nguyên ổ cứng.
Lưu ý: Với một số trường hợp bắt lỗi data nhạy cảm nên trả về lỗi chung chung tránh nếu quá chi tiết, ví dụ: sai username hoặc password... .Thay vì tăng tính bảo mật thì chúng ta lại cung cấp thêm thông tin để hacker khai thác lỗ hổng.
Kinh nghiệm cá nhân: Validate dữ liệu nhiều hơn, kỹ hơn sẽ ngủ ngon hơn 🤣
4. Return required data
Sau kiểm tra dữ liệu đầu vào thì chúng ta cần lọc dữ liệu đầu ra trước khi trả lại cho người dùng. Thông thường sẽ cho data đi DTO (Data Transfer Object) để lọc bớt dữ liệu và loại bỏ các thông tin nhạy cảm như: password, key, ...Trong khi triển khai API, các lập trình vô tình bỏ qua bước này, đây là một trong những lỗi cơ bản nhất làm cho hệ thống bị khai thác dễ dàng hơn. Một số công dụng của cách làm trên:
- Tất nhiên che giấu bảo vệ thông tin có giá trị của người dùng.
- Giảm dư thừa dữ liệu và tăng tốc độ API, nếu chỉ trả về data cần thiết thì kích thước data cũng nhỏ hơn giúp tăng tốc độ gửi nhận.
5. Use Rate Limiting
Đây là một biện pháp chống DDos cực tốt, thông thường các cuộc tấn DDos sẽ gửi lượng request lớn và liên tục trong thời gian để làm ứng dụng bị quá tải và không thể xử lý kịp, làm gián đoạn dịch vụ. Chúng ta cần giới hạn số request/giây đối với một người dùng, có thể block người dùng đó nếu cố tình gửi nhiều hơn số lượng request cho phép. Ngoài ra, đối với các API có tần suất request nhiều có thể xem xét để áp dụng cache kết hợp. Ngăn chặn tiêu thụ và sử dụng tài nguyên của server quá mức.
Giống như chiến binh ở trên, vẫn luôn còn điểm yếu mà hacker có thể khai thác để tấn công được (tấm chắn mặt vẫn có nguy cơ bị tên xuyên qua), hacker có thể thăm dò và đoán giới hạn request/giây của hệ thống, từ đó giãn thời gian gọi request của mỗi người dùng ảo nhưng lại tăng số lượng người dùng ảo lên để tiến hành DDos. Nhưng áp dụng biện pháp trên cũng tăng thêm phần khó khăn khi muốn DDos vào hệ thống.
Chia sẻ: mình cũng từng sử dụng API bên thứ 3 với lượng rate limiting thấp, tầm 3 request/giây để có thể sử dụng mượt mà không bị block account thì mình đã thêm timeout vào mỗi request để giãn thời gian gọi request
6. Security testing
Cũng thường hay bị lãng quên như việc viết Unit Test và thường nhờ các bác hacker làm hộ hoặc hệ thống bắt đầu có vấn đề mới được quan tâm đến. Việc thường xuyên thực hiện các bài kiểm tra bảo mật lên hệ thống giúp phát hiện và tìm ra biện pháp xử lý sớm, khắc phục trước khi bị khai thác và tấn công.
Nên lập kế hoạch triển khai các kịch bản giả tấn công phổ biến, có thể tham khảo các lỗi bảo mật ở OWASP để lên kịch bản. Cũng tuỳ thuộc vào hệ thống hiện tại để có các kịch bản, trường hợp đặc biệt kiểm tra tính an toàn hệ thống. Nếu không có quá nhiều thời gian có thể cân nhắc thực hiện trong các đợt release lớn hoặc tính năng có liên quan đến độ an toàn của hệ thống.
Hình ảnh được cắt và tham khảo từ nguồn:
ref: Rapid API
Bên trên là một số biện pháp và cách thức mình tổng hợp được nếu các bạn có biện pháp nào hay hơn tốt hơn có thể comment góp ý. Good luck for you