HTML escape/unescape khi debug entity | Khác XSS sanitize thế nào【2026】

(Cập nhật: 19 tháng 7, 2026 ) HTML escape unescape HTML entity XSS debug sanitize
Kết luận

Escape/unescape là thao tác debug entity, không phải tường lửa XSS. Dùng khi log/CMS hiện <div> hoặc & và bạn cần đọc / đối chiếu một lớp encoding. Chống XSS thật sự = escape đúng context khi render hoặc sanitize allowlist nếu bắt buộc HTML giàu — cộng CSP. HTML Escape trên Kawa: escape/unescape local trên trình duyệt, không thay DOMPurify hay policy bảo mật của app.

Sinh viên và freelancer Việt Nam hay gặp cảnh này trên Slack: khách gửi screenshot CMS — tiêu đề hiện nguyên & Khuyến mãi <b>50%</b>. Ai đó bảo “escape lại là xong”, người khác bảo “cài thư viện XSS”. Hai việc khác mục đích.

Bài này đi theo góc escape/unescape để debug entity nhanh, phân biệt rõ với sanitize chống XSS, kèm ví dụ double-encode và checklist context (body / attribute / JS).

Bài viết này giúp bạn

  • Hiểu entity (<, &, ", ') và vì sao chúng xuất hiện
  • Phân biệt escape debug vs sanitize XSS
  • Nhận double-encode (&) và cách gỡ từng lớp
  • Biết khi nào không được unescape rồi nhét lại innerHTML
  • Dùng tool trình duyệt trong 30 giây khi review bug

Escape là gì — và không phải gì

Escape (mã hóa entity)

Đổi ký tự có nghĩa trong HTML thành dạng an toàn để hiển thị như chữ:

Ký tựEntity thường dùng
&&
<&lt;
>&gt;
"&quot;
'&#39; hoặc &#x27;

Ví dụ:

Input:  <script>alert('x')</script>
Escape: &lt;script&gt;alert(&#39;x&#39;)&lt;/script&gt;

Trình duyệt không chạy script — nó vẽ ra chữ <script>.... Đó là đúng khi bạn muốn text, không phải HTML.

Unescape (giải mã entity)

Làm ngược lại: &lt;<. Hữu ích khi đọc dữ liệu đã entity-hóa. Không biến chuỗi không tin cậy thành HTML an toàn.

Sanitize (chống XSS) — lớp khác

Sanitize giữ subset HTML (ví dụ <p>, <strong>) và loại <script>, onerror=, javascript:. Thư viện kiểu DOMPurify làm việc này. Escape thuần không cho phép “HTML giàu an toàn” — nó biến mọi thứ thành text.

Escape vs Unescape vs Sanitize
Thao tác Mục đích Khi nào dùng
Escape Text an toàn trong HTML Render user input dạng chữ; chuẩn bị snippet demo
Unescape Đọc lại bản rõ từ entity Debug CMS/API/log bị encode
Sanitize HTML giàu nhưng cắt payload Rich text editor, comment cho phép thẻ giới hạn

Góc debug: khi nào bấm Unescape trước

1. Log hoặc email hiện entity

User name: Nguy&#7877;n &amp; Co.

Unescape (hoặc decode đúng charset) để xác nhận tên thật trước khi đổ lỗi font tiếng Việt. Lưu ý: một số chuỗi là decimal/hex numeric character reference (&#7877;) — tool escape cơ bản có thể không phủ hết mọi dạng; khi đó cần decoder Unicode chuyên biệt.

2. CMS / headless API double-encode

Pipeline điển hình:

  1. Editor lưu <b>Sale</b>
  2. Middleware escape → &lt;b&gt;Sale&lt;/b&gt;
  3. Template escape lần nữa → &amp;lt;b&amp;gt;Sale&amp;lt;/b&amp;gt;

Màn hình khách thấy chữ &lt;b&gt;... thay vì in đậm. Unescape một lần trên HTML Escape giúp thấy lớp giữa; sửa bằng cách bỏ một lớp escape trong code — không escape thêm lần ba.

3. So sánh snapshot test

Test snapshot bắt entity; mắt người khó đọc. Unescape tạm để review diff nội dung, rồi giữ snapshot dạng escaped nếu đó là contract API.

4. Copy từ DevTools “Copy outerHTML”

Đôi khi bạn copy nhầm chuỗi đã escape trong attribute. Unescape để lấy payload gốc trước khi tái hiện bug.


Context quyết định — escape “đúng chỗ”

Cùng một chuỗi user, context khác → rule khác:

ContextCách an toàn phổ biếnSai thường gặp
Text node HTMLEscape & < > (framework thường làm sẵn)innerHTML = userText không escape
Attribute value="..."Escape cả dấu "Chỉ escape < rồi vỡ attribute
URL queryPercent-encode, không chỉ HTML entityNhét entity vào URL rồi expect server hiểu
JS trong <script>JSON.stringify / CSPUnescape HTML rồi nối chuỗi JS

React / Vue: nội dung trong {user} / {{ user }} thường đã escape. Nguy hiểm khi dangerouslySetInnerHTML / v-html với HTML từ CMS — lúc đó cần sanitize, không phải chỉ bấm Escape trên tool rồi dán vào.


Công cụ Kawa làm gì (và không làm gì)

HTML Escape hỗ trợ:

  • Escape: & < > " ' → entity (&amp; &lt; &gt; &quot; &#39;)
  • Unescape: các entity trên (+ &#x27;) → ký tự gốc
  • Chạy 100% trên trình duyệt — phù hợp snippet nội bộ

Không phải:

  • Bộ lọc XSS đầy đủ / allowlist thẻ
  • Decoder mọi numeric entity Unicode tiếng Việt
  • Thay CSP, HttpOnly cookie, hay audit bảo mật

Workflow gợi ý:

  1. Dán đoạn nghi ngờ
  2. Unescape nếu đang đầy &lt; / &amp; — đọc nội dung
  3. Escape một lần nếu cần entity sạch để nhúng text
  4. Quay lại code: sửa chỗ encode thừa hoặc chỗ render sai context

Case study

Outsourcing: form liên hệ hiện thẻ <br>

Khách nhập xuống dòng; backend lưu có <br>; frontend escape → hiện chữ <br>. Product muốn xuống dòng thật.

  • Sai: unescape rồi innerHTML — mở XSS nếu ai đó nhập <img onerror=...>.
  • Đúng hơn: lưu newline thuần, render bằng CSS white-space / tách đoạn; hoặc sanitize allowlist chỉ <br> / <p>.

Bug &amp;amp; trên title SEO

Title trong DB đã là A & B. Layer OGP escape → A &amp; B. Layer theme escape lại → A &amp;amp; B trên tab trình duyệt.

Debug: unescape dần trên tool → thấy chỉ cần một lớp escape ở biên HTML. Bookmark checklist “ai đang escape?” cho team.


Checklist 5 phút khi thấy entity lạ

  1. Đây là text cần hiện nguyên hay HTML có chủ đích?
  2. Đếm lớp: có &amp;amp; / &amp;lt; không?
  3. Unescape trên tool để đọc — không deploy chuỗi unescape vào innerHTML.
  4. Xác định context: body, attribute, URL, hay JS.
  5. Framework đã escape sẵn chưa? Có v-html / dangerouslySetInnerHTML không?
  6. Cần HTML giàu → sanitize + CSP; chỉ cần chữ → escape một lần đúng chỗ.

Câu hỏi thường gặp

Escape khác sanitize thế nào?
Escape → text entity. Sanitize → HTML giàu đã cắt payload. Unescape chỉ để đọc/debug.

Khi nào unescape?
CMS/API/log đã entity-hóa; double-encode; review snapshot. Không dùng unescape như “vá XSS”.

Chỉ escape < > có đủ?
Không đủ mọi context — attribute và JS cần rule riêng; framework text node thường đủ hơn innerHTML thủ công.

Tool có upload dữ liệu không?
Kawa HTML Escape chạy local trên trình duyệt.

Thấy &amp;amp; thì sao?
Escape hai lần — gỡ một lớp trong pipeline, đừng escape thêm.

Liên kết liên quan