- Một researcher vừa nhắc lại sự thật khó chịu: WAF normalize tất cả ký tự về lowercase chỉ là mẹo tối ưu rule, không phải lớp phòng thủ.
- XSS đánh cắp cookie vẫn xuyên qua, và đây là lý do.
TL;DR
Researcher @tor_zhi vừa chia sẻ một payload XSS đánh cắp cookie chạy được trên trang có WAF rất chặt — WAF đó normalize toàn bộ input về chữ thường, giết hầu hết payload cheat-sheet. Điểm đáng nói không phải payload cụ thể, mà là: lowercase normalization là công cụ tối ưu rule, không phải lớp sanitizer. HTML vốn đã case-insensitive, nên hạ chữ thường không ngăn được gì về mặt thực thi — nó chỉ giúp regex đỡ phải viết thêm biến thể hoa/thường.
Chuyện gì vừa xảy ra
Trong một report bị đánh dấu trùng, @tor_zhi công bố payload thực tế đánh cắp cookie trên một target có WAF khét tiếng khó chịu. Điểm đặc biệt của WAF: nó chuyển toàn bộ request body/query về lowercase trước khi đưa vào rule engine. Rất nhiều payload phổ biến — những payload dựa vào tag mixed-case như <ScRiPt> hoặc từ khoá viết hoa để né blocklist — bị vô hiệu hoàn toàn. Vậy mà cookie vẫn bay về máy attacker.
Bài toán này không mới. Năm 2023, Asem Eleraky đã công bố một write-up đánh cắp cookie khi WAF chặn cả (, ), /, :, + — dùng backtick (tagged template) và Array.join với template string để lắp ráp URL. Kỹ thuật đó cũng miễn nhiễm với lowercase normalization.
Vì sao chuyện này quan trọng
Nhiều team dùng WAF như cái "tường lửa cuối cùng" và tin rằng bật rule OWASP Top 10 + text-transform LOWERCASE là đủ. Trên thực tế, WAF lowercase chỉ giải quyết vấn đề kỹ thuật của rule writer: không phải viết cả script lẫn ScRiPt lẫn SCRIPT. Nó không thay đổi bề mặt tấn công, vì:
- Trình duyệt match tên thẻ và attribute không phân biệt hoa thường sẵn —
<IMG onerror=...>và<img onerror=...>chạy như nhau. - Payload không cần từ khoá in hoa để né lowercase filter — nó cần không khớp pattern rule, và có rất nhiều cách.
- Output encoding, CSP, HttpOnly cookie nằm ở tầng khác và mới là thứ thực sự chặn exfiltration.
Những lớp bypass sống sót qua lowercase
Dưới đây là các hướng payload mà lowercase normalization không làm khó được. Chúng tôi cố tình mô tả ở mức khái niệm để phục vụ defender; payload chi tiết có trong các cheat sheet công khai.
- Syntax thay thế: backtick tagged template (
alert`1`) thay choalert(1). Khi(,+,/,:bị chặn, attacker dùng[origin, host, path, cookie].join``để lắp URL. - DOM event handler ít phổ biến:
onbeforetoggle,oncommand,onpointerrawupdate,onscrollend. Bản XSS Cheat Sheet 2026 của PortSwigger liệt kê rất nhiều handler mới không nằm trong rule cũ. - SVG event:
<animate onbegin=...>,onend,onrepeatchạy trong context SVG mà nhiều ruleset bỏ qua. - HTML entity & numeric encoding: attribute value có thể dùng
javascript:.... Lowercase chỉ đi qua chuỗi thô — browser mới là nơi decode entity. - Parameter pollution & split across params: tách payload thành nhiều query params, WAF đánh giá từng param riêng, browser ghép lại trong DOM.
So sánh: WAF lowercase vs phòng thủ thật
| Control | Chặn XSS thực thi? | Chặn cookie theft? |
|---|---|---|
| WAF lowercase + keyword blocklist | Không — nhiều lớp bypass sống sót | Không |
| Output encoding theo context | Có (khi đúng context) | Có |
| CSP strict-dynamic + nonce | Có trong hầu hết case | Có (chặn fetch tới host lạ) |
| HttpOnly + Secure + SameSite cookie | Không (XSS vẫn chạy) | Phần lớn có — trừ khi dính "cookie sandwich" |
| Trusted Types | Có (DOM sink) | Có |
Lưu ý ô cuối cùng: tháng 3/2025 PortSwigger công bố cookie sandwich — kỹ thuật lợi dụng lỗi parse cookie của một số server để lộ cả HttpOnly cookie qua JS. Tức là ngay cả HttpOnly cũng không phải vô địch nếu app xử lý cookie lỏng lẻo.
Ai cần đọc cái này
- Bug bounty hunter: gặp WAF lowercase thì đừng bỏ cuộc — chuyển sang backtick, DOM event mới, SVG, entity encoding.
- AppSec / product security: audit xem team có đang coi WAF là defense duy nhất không. Nếu có, bạn đang một cái
onbeforetogglenữa là ăn report. - DevOps cấu hình AWS WAF / Cloudflare / Azure WAF: đọc kỹ doc — text-transform
LOWERCASElà tối ưu rule, không phải sanitizer. - Developer: output encoding theo context, CSP nonce, cookie HttpOnly/Secure/SameSite — ba thứ này mới là hàng rào thật.
Giới hạn & lưu ý
Đây không phải CVE mới. Không có vendor nào "fix" được vì WAF lowercase vận hành đúng thiết kế — vấn đề nằm ở người cấu hình coi nó như lớp chống XSS cuối cùng. HttpOnly cookie giảm đáng kể rủi ro cookie theft, nhưng không phải tuyệt đối (xem cookie sandwich). CSP chặn exfil tới host lạ nhưng cấu hình sai (quá nhiều unsafe-inline, whitelist CDN quá rộng) làm nó gần như vô dụng.
Tiếp theo là gì
Hai xu hướng đáng theo dõi. Một, ruleset WAF sẽ phải chạy đua với danh sách DOM event handler mới của browser — nhưng browser thêm handler nhanh hơn vendor cập nhật rule. Hai, attacker đang chuyển dần sang gadget chain tương thích Trusted Types và các kỹ thuật exfil lợi dụng chính CSP-nonce của site. Hướng phòng thủ đúng vẫn là nhiều lớp: output encoding + CSP + HttpOnly + Trusted Types, chứ không phải tin một con WAF nào sẽ giải quyết tất cả.
Nguồn: @tor_zhi tweet, Asem Eleraky write-up, PortSwigger XSS Cheat Sheet 2026, PortSwigger cookie sandwich research.