Trong HTML, các ký tự <, > và & mang ý nghĩa đặc biệt và cần được escape. Nhưng với tiếng Việt, vấn đề thú vị hơn nằm ở chỗ mỗi chữ có dấu thực chất là một tổ hợp nhiều ký tự Unicode chồng lên nhau — và điều đó ảnh hưởng trực tiếp đến cách entity số hoạt động.
Một chữ, nhiều ký tự Unicode: dựng sẵn và tổ hợp
Chữ "ệ" trong "việc" có thể được lưu theo hai cách hoàn toàn khác nhau về mặt byte: dạng dựng sẵn (precomposed, NFC) là một điểm mã Unicode duy nhất, hoặc dạng tổ hợp (NFD) gồm chữ "e" cộng với hai dấu kết hợp riêng biệt (dấu mũ và dấu nặng) xếp chồng lên nhau. Khi chuyển sang entity số, hai cách lưu trữ này cho ra chuỗi entity dài ngắn khác nhau cho cùng một chữ hiển thị y hệt — đây là nguồn gây nhầm lẫn phổ biến khi so sánh chuỗi văn bản tiếng Việt sau khi mã hoá.
Vì sao dấu thanh khiến chuỗi entity dài bất thường
Tiếng Việt có tới 5 dấu thanh (huyền, sắc, hỏi, ngã, nặng) kết hợp với các nguyên âm đã có dấu phụ (â, ê, ô, ơ, ư), tạo ra hàng chục tổ hợp không tồn tại trong bảng chữ cái Latin gốc. Nếu một hệ thống cũ cần chuyển văn bản tiếng Việt hoàn toàn sang entity số (ví dụ để tương thích với hệ thống không hỗ trợ UTF-8), một câu ngắn có thể phình to gấp nhiều lần so với văn bản gốc.
Bộ ký tự tối thiểu cần escape
<→<— để không bắt đầu một thẻ.>→>— để đóng văn bản đúng cách sau một thẻ.&→&— để dấu & không bị hiểu là bắt đầu của entity khác."và'→",'— bắt buộc bên trong giá trị thuộc tính trong dấu ngoặc kép.
Mối liên hệ với XSS
Hầu hết các lỗ hổng XSS phát sinh chính vì văn bản do người dùng nhập được chèn vào HTML mà không escape. Hiển thị "<script>...</script>" mà không chuyển thành entity sẽ khiến trình duyệt thực thi nó như mã. Escape là biện pháp bảo vệ cơ bản — nhưng không phải duy nhất.
Ngữ cảnh quan trọng: văn bản so với thuộc tính
Escape <, > và & là đủ cho văn bản nằm giữa các thẻ, nhưng bên trong một thuộc tính đặt trong dấu ngoặc kép, cần escape thêm chính loại dấu ngoặc được dùng — kép hay đơn. Nếu thuộc tính được giới hạn bằng dấu ngoặc kép mà giá trị chứa một dấu ngoặc kép chưa escape, mã đánh dấu sẽ "đứt" sớm hơn dự kiến.