Validate đầu vào và encode đầu ra khác nhau như thế nào?
Đáp án mẫu
Validate đầu vào kiểm tra dữ liệu có chấp nhận được hay không khi vào hệ thống: kiểu, độ dài, khoảng giá trị, định dạng và quy tắc nghiệp vụ. Encode đầu ra biến đổi dữ liệu khi nó đi ra, để bên nhận coi nó là dữ liệu thuần chứ không phải code.
Validate tốt nhất là dùng allow-list ngay tại biên: tuổi là số nguyên từ 0 đến 150, quốc gia thuộc một tập đã biết, username khớp ^[a-z0-9_]{3,20}$. Từ chối sớm kèm thông báo lỗi rõ ràng. Cách này thu hẹp bề mặt tấn công và giữ dữ liệu sạch, nhưng không thể là lớp phòng thủ duy nhất, vì có những đầu vào hợp lệ như tên O'Brien hay bình luận chứa <b> vẫn nguy hiểm khi đặt sai chỗ.
Cách encode phụ thuộc vào đích đến: escape HTML cho HTML, bind tham số cho SQL, truyền mảng argument cho lệnh shell, URL encoding cho URL. Cùng một chuỗi cần được xử lý khác nhau ở mỗi nơi.
Cách kết hợp thường dùng: validate khi nhận, encode khi xuất, dùng mặc định của framework như auto-escape của template.
Điều cần nhớ: validate thu hẹp thứ đi vào; encode làm cho mọi thứ đi ra an toàn với ngữ cảnh của nó.
Ý chính
- Validate kiểm tra dữ liệu lúc đi vào
- Encode làm dữ liệu an toàn lúc đi ra
- Ưu tiên allow-list hơn block-list
- Encode phải đúng với ngữ cảnh đầu ra
Câu hỏi nối tiếp thường gặp
- Vì sao danh sách chặn ký tự xấu yếu?
- Bạn validate ở đâu: client, API gateway hay service?
Lỗi thường gặp
- Tin rằng đầu vào đã validate thì an toàn ở mọi nơi
- Encode một lần lúc nhận thay vì ở mỗi đầu ra