Đây là ví dụ ngớ ngẩn lừa dối bằng cách lạm dụng htmlspecialchars
từ cách bạn dự định.
<?php
$s = htmlspecialchars($_GET['x'], ENT_QUOTES);
$s_utf8 = htmlspecialchars($_GET['x'], ENT_QUOTES, 'UTF-8');
if(!empty($s))
print "default: " . $_GET['x'] . "<br>\n";
if(!empty($s_utf8))
print "utf8: " . $_GET['x'] . "<br>\n"
?>
Gửi bất kỳ tải trọng XSS nào và thêm byte UTF-8 không hợp lệ, ví dụ:
http://site/silly.php?x=<script>alert(0)</script>%fe
htmlspecialchars
bails trên một chuỗi không hợp lệ UTF-8 byte và trả về một chuỗi rỗng. In ấn giá trị $_GET
là một lỗ rõ ràng, nhưng tôi có một điểm để thực hiện.
Tóm lại, bạn sẽ nhận các kiểm tra byte-by-byte với Latin1 và UTF-8 vì vậy tôi không biết về ví dụ phụ thuộc vào ngôn ngữ nơi htmlspecialchars
sẽ bỏ lỡ một byte nguy hiểm trong một mã hóa, nhưng không khác.
Điểm của ví dụ của tôi là câu hỏi của bạn là tổng quát hơn (và có lẽ hơi quá mơ hồ) đối với sự nguy hiểm của XSS khi thay đổi lược đồ mã hóa. Khi nội dung bắt đầu xử lý mã hóa nhiều byte khác nhau, nhà phát triển có thể làm hỏng bộ lọc xác thực dựa trên strchr()
, strlen()
hoặc các kiểm tra tương tự không nhận thức được nhiều byte và có thể bị chặn bởi% 00 trong tải trọng. (Hey, một số dev vẫn giữ sử dụng regex để phân tích và khử trùng HTML.)
Về nguyên tắc, tôi nghĩ rằng hai dòng ví dụ trong câu hỏi có độ an toàn ngang nhau. Trong thực tế, vẫn còn rất nhiều cách để làm cho những sai lầm khác với mã hóa không rõ ràng.
Đây là câu trả lời rất hay. Cảm ơn bạn. – rook