Security checklist cho web developer
Phát triển các ứng dụng web an toàn mà vẫn mạnh mẽ là một việc làm rất khó. Nếu bạn nghĩ nó rất dễ dàng, thì hoặc là bạn rất giỏi hoặc là bạn sắp gặp ác mộng. Danh sách dưới đây là một danh sách tổng hợp những gì mà một người cần quan tâm khi bảo mật cho những ứng dụng của mình. Nếu bỏ qua điều ...
Phát triển các ứng dụng web an toàn mà vẫn mạnh mẽ là một việc làm rất khó. Nếu bạn nghĩ nó rất dễ dàng, thì hoặc là bạn rất giỏi hoặc là bạn sắp gặp ác mộng.
Danh sách dưới đây là một danh sách tổng hợp những gì mà một người cần quan tâm khi bảo mật cho những ứng dụng của mình. Nếu bỏ qua điều gì, bạn nên dũng cảm mà cảnh báo người dùng rằng, ứng dụng của bạn vẫn chưa thực sự bảo mật.
- Đã mã hóa hết tất cả dữ liệu dùng để xác nhận người dùng cùng với các dữ liệu "nhạy cảm" khác, ví dụ như access token, email, thông tin credit card, v.v...
- Nếu cơ sở dữ liệu hỗ trợ các phương pháp mã hóa dữ liệu dạng lưu trữ với chi phí thấp (ví dụ như AWS Aurora), hãy sử dụng nó để bảo mật dữ liệu. Hãy đảm bảo rằng tất cả các bản sao lưu cũng đều được mã hóa.
- Hãy phân quyền cho người dùng và chỉ cấp cho họ quyền tối thiểu. Không bao giờ sử dụng tài khoản root cho cơ sở dữ liệu.
- Lưu trữ và phân phối các dữ liệu mật bằng các khóa riêng biệt. Đừng hard code khóa này (sử dụng biến môi trường là một giải pháp).
- Phòng chống SQL Inject một cách triệt để bằng việc sử dụng các câu SQL với tham số. Tức là hãy sử dụng query kiểu SELECT * FROM users WHERE name = ? thay vì SELECT * FROM users where name = #{user_input}. Tuy nhiên, tốt nhất, hãy sử dụng ORM.
- Đảm bảo tất cả các thành phần của code đều được kiểm tra các lỗ hổng bảo mật trước khi public lên production (bao gồm cả các thư viện của bên thứ ba). Tốt nhất, hãy tự động hóa những thao tác này qua CI/CD.
- Bảo mật môi trường phát triển cũng như bạn bảo mật production. Hãy phát triển trong một môi trường biệt lập và bảo mật.
- Đảm bảo password được hash bằng phương thức thích hợp (ví dụ bcrypt). Đừng tự viết phương thức mã hóa cho riêng mình (vì bạn sẽ phải bỏ ra rất nhiều công sức và thời gian mới có thể xây dựng được một phương pháp mã hóa đủ bảo mật) và hãy sử dụng khóa càng ngẫu nhiên càng tốt.
- Đưa ra các quy tắc đơn giản nhưng đủ bảo mật cho password (về số ký tự, các quy tắc cho chữ cái, chữ số, ký tự đặc biệt, v.v...), sao cho người dùng đặt mật khẩu đủ dài (và ngẫu nhiên càng tốt)
- Sử dụng nhiều lớp xác thực (thông thường thì 2 lớp đã tương đối tốt rồi, nhưng nếu cần thì vẫn nên tăng lên)
- Đảm bảo rằng các cuộc tấn công DoS không làm sập trang web của bạn. Ít nhất, hãy giới hạn việc truy cập vào các API như login hoặc lấy token. Hãy sử dụng một số phương pháp như CAPTCHA để bảo vệ hệ thống.
- Đặt các giới hạn về kích thước và cấu trúc của dữ liệu được gửi lên từ người dùng.
- Sử dụng các công cụ giảm nhẹ tấn công Distributed Denial of Service (DDOS) như sử dụng các hệ thông cache CloudFlare. Bạn có thể bật chúng lên khi bị tấn công và tắt đi cho các lưu thông bình thường.
- Sử dụng TLS cho toàn bộ trang web. Đừng chỉ sử dụng TLS cho một vài trang như login hoặc thanh toán.
- Cookie nên được đặt httpOnly và phân biệt theo path và domain.
- Sử dụng CSP mà không cho phép các backdoors unsafe-*. Cấu hình điều này có thể là một cực hình nhưng cần thiết.
- Sử dụng X-Frame-Option, X-XSS-Protection header khi phản hồi.
- Sử dụng HSTS để bắt buộc sử dụng TLS. Redirect toàn bộ HTTP về HTTPS.
- Sử dụng CSRF token cho tất cả các form và SameSite Cookie để fix lỗi CSRF.
- Đảm bảo rằng không API nào cho phép người dùng có thể duyệt nhiều dữ liệu, nhằm cách những tấn công dạng brute force. Tốt nhất mỗi API chỉ trả về lượng dữ liệu tối thiểu, càng dư thừa, kẻ tấn công càng có nhiều thông tin về hệ thống.
- Đảm bảo người dùng được xác thực và phân quyền cẩn thận khi sử dụng API.
- Validate bên client (thường bằng JS) là cần thiết để cho trải nghiệm người dùng tốt hơn. Nhưng không bao giờ được tin tưởng vào chúng. Dù có validate phía client rồi, server vẫn cần validate thêm một lần nữa.
- Validate tất cả những gì người dùng nhập vào. Nên sử dụng whitelist trên server (sử dụng blacklist cũng được nhưng sẽ kém an toàn hơn do chúng ta có thể bỏ sót một vài trường hợp). Không bao giờ được tin tưởng vào những gì người dùng nhập vào, không đưa nó vào câu truy vấn SQL, không hiển thị nó trên trang web mà không có các biện pháp thanh lọc.
- Đảm bảo tất cả dịch vụ chỉ mở port cần thiết. Mặc dù mở cổng nhiều khi cũng không hại gì, nhưng đề phòng vẫn là tốt nhất.
- Dùng DB server và các dịch vụ khác tương tự trên VPC private (không cho phép truy cập từ bên ngoài). Hãy cẩn thận với Security group nếu bạn sử dụng AWS (peering VPC có thể bị public ngoài ý muốn).
- Các server độc lập về logic cần được phân tách về các server độc lập về vật lý. Cung cấp phương tiện kết nối trong mạng nội bộ giữa chúng, và chỉ cho chúng kết nối trong mạng nội bộ mà thôi.
- Đảm bảo các dịch vụ chỉ chấp nhận truy cập từ một hoặc một số địa chỉ IP nhất định.
- Giới hạn IP và port ra ngoài với những API luôn ở mức tối thiểu.
- Luôn sử dụng AWS IAM roles thay cho root.
- Chỉ cung cấp quyền truy cập tối thiểu cho mọi thành viên.
- Thường xuyên thay đổi password và access key
- Đảm bảo rằng bạn có thể nâng cấp hệ thống mà không làm gián đoạn nó. Hãy tự động hóa việc này để nâng cấp trở nên dễ dàng hơn.
- Sử dụng các công cụ như Terraform cho công việc Infra, thay vì ssh và gõ lệnh. Infra nên được định nghĩa bằng "code" (DevOps cũng đang là xu thế mới nổi), và có thể dễ dàng thay đổi chỉ bằng vài click. Không làm bằng tay bất cứ thao tác nào, Terraform có thể giúp bạn mọi việc.
- Sử dụng các dịch vụ log và theo dõi log. Bạn có thể tham khảo bài viết này để biết thêm một số công cụ. Không bao giờ bạn cần để ssh để xem log.
- Không bao giờ ssh vào các dịch vụ. Thường xuyên sử dụng ssh đồng nghĩa với việc bạn chưa tự động hóa một trong số những thao tác quan trọng nhất.
- Không mở cổng 22 thường xuyên cho bất cứ dịch vụ nào. Thay vào đó, hãy giới hạn việc truy cập bằng ssh với một vài IP mà thôi.
- Tạo immutable hosts thay thế cho các máy chủ. Bằng cách này bạn sẽ dễ dàng nâng cấp hơn. Tham khảo thêm bài viết này.
- Sử dụng Intrusion Detection System, ví dụ SenseDeep để giảm thiểu APTs.
- Tắt các dịch vụ không cần thiết. Một máy chủ được bảo mật khi và chỉ khi nó đã bị tắt.
- Kiểm tra thiết kế hệ thống và việc triển khai nó.
- Kiểm tra xâm nhập bằng cách tự hack mình, nhưng bạn nên nhờ người khác nữa. Tự mình test code của mình chúng ta dễ xảy ra suy nghĩ "code thế này thì lỗi thế nào được?". Thuê một chuyên gia bảo mật là tốt nhất.
- Bạn cần biết rõ về những thứ mà mình cần đối phó. Tốt nhất là hãy lên danh sách về các mối nguy hại và phương án đề phòng và sắp xếp chúng theo thứ tự ưu tiên.
- Xây dựng kế hoạch đối phó với khủng hoảng. Bây giờ bạn chưa dùng đến nó đâu, và có thể bạn thấy nó thật thừa thãi. Nhưng không có gì đảm bảo hệ thống của bạn an toàn, có thể một ngày nào đó, bạn sẽ cần đến những phương án này.
Bài viết gốc: https://manhhomienbienthuy.bitbucket.io/2017/Jun/12/web-developer-security-checklist.html (đã xin phép tác giả