Vì trình duyệt parse mỗi vị trí trong trang theo một bộ luật khác nhau. Chuỗi đã escape đúng cho thân HTML vẫn có thể thoát ra ở ngữ cảnh khác.
Bốn ngữ cảnh cần nhớ:
| Vị trí | Cần làm |
|---|---|
Thân HTML <div>HERE</div> | Escape < > & " ' |
Giá trị thuộc tính <div title="HERE"> | Escape như trên và bắt buộc bọc nháy |
Trong <script> | Encode theo luật JS string, an toàn nhất là truyền qua JSON.stringify |
URL <a href="HERE"> | encodeURIComponent và kiểm tra scheme |
Ví dụ thuộc tính không bọc nháy — escape HTML không cứu được:
html
<div class=HERE> <!-- HERE = x onmouseover=alert(1) -->Ví dụ ngữ cảnh URL — encodeURIComponent không chặn scheme:
jsx
<a href={userUrl}>Trang cá nhân</a> // userUrl = javascript:alert(1)Phải kiểm tra tường minh:
js
const u = new URL(userUrl, location.origin)
if (u.protocol !== 'http:' && u.protocol !== 'https:') throw new Error('bad scheme')Chốt: đừng escape thủ công.
Dùng template engine tự động escape theo ngữ cảnh (React, Vue, Thymeleaf, Razor), và khi buộc phải ghép chuỗi thì phải biết rõ mình đang ghép vào ngữ cảnh nào.