2011-01-07 30 views
5

Cho phép nói rằng tôi có một ứng dụng web đang sử dụng Latin1 hoặc một số mã hóa tiếng Anh mặc định. Tôi muốn thay đổi ứng dụng để sử dụng UTF-8 hoặc có thể là mã hóa ngôn ngữ khác. Bạn có thể chứng minh rằng thay đổi này sẽ giới thiệu XSS không?XSS có thể được giới thiệu bằng cách thay đổi mã hóa ngôn ngữ không?

Đây không phải là câu hỏi cụ thể về PHP, nhưng trong PHP, bạn có thể hiển thị trường hợp htmlspecialchars($var,ENT_QUOTES); dễ bị tổn thương đối với XSS và htmlspecialchars($var,ENT_QUOTES,'UTF-8'); thì không.

Trả lời

1

Từ RFC 3629:

10. Xem xét an ninh

tượng thực hiện UTF-8 cần phải xem xét các khía cạnh an ninh như thế nào họ xử lý chuỗi bất hợp pháp UTF-8. Đó là có thể hiểu rằng trong một số trường hợp, kẻ tấn công có thể khai thác trình phân tích cú pháp UTF-8 không mong muốn bằng cách gửi một chuỗi octet không phải là được phép theo cú pháp UTF-8.

Một hình thức đặc biệt tinh tế của cuộc tấn công này có thể được thực hiện chống lại một phân tích cú pháp , thực hiện kiểm tra tính hợp lệ an ninh quan trọng so với UTF-8 hình thức mã hóa đầu vào của nó, nhưng giải thích một số bất hợp pháp chuỗi octet như ký tự . Đối với ví dụ , trình phân tích cú pháp có thể cấm ký tự N2 NUL khi được mã hóa là chuỗi octet đơn 00, nhưng cho phép một cách sai lầm chuỗi hai octet bất hợp pháp C0 80 và giải thích dưới dạng ký tự NUL.Ví dụ khác có thể là một trình phân tích cú pháp mà cấm chuỗi octet 2F 2E 2E 2F ("/../"), nhưng cho phép trình tự octet bất hợp pháp 2F C0 AE 2E 2F. lần khai thác cuối cùng này thực sự đã được sử dụng trong một loại vi-rút phổ biến tấn công các máy chủ Web vào năm 2001; do đó, mối đe dọa an ninh là rất thực tế.

Vì vậy, điều quan trọng là phải xác định rằng dữ liệu của bạn hợp lệ UTF-8.

Nhưng một khi bạn đã thực hiện việc này, mối quan tâm về bảo mật liên quan đến việc mã hóa là tối thiểu. Tất cả các ký tự đặc biệt HTML đều có dạng ASCII và UTF-8 như ISO-8859-1 tương thích hoàn toàn với ASCII. htmlspecialchars sẽ hoạt động theo cách bạn mong đợi.

Có nhiều mối quan ngại với mã hóa tương thích không phải ASCII. Ví dụ: trong GB18030, các byte ASCII 0x30 trở lên có thể xảy ra trong bảng mã của ký tự nhiều byte. Ký tự HYPHEN (U + 2010) được mã hóa là A9 5C, bao gồm dấu gạch chéo ngược ASCII. Điều này khiến cho việc xử lý dấu gạch chéo ngược trở nên khó khăn hơn, hãy mời SQL injection.

+0

Đây là câu trả lời rất hay. Cảm ơn bạn. – rook

4

Đâ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.

+0

+1, thú vị. – rook

+0

Tôi đoán một điểm khác mà tôi có thể thực hiện là "Biết xử lý lỗi của bạn" - nó có thể xử lý khá phức tạp với các mã byte không hợp lệ hoặc bị bất ngờ bởi các hành vi không mong muốn. – Mike

+0

yeah Tôi đồng ý, các chức năng khác có thể lỗi và trả về một chuỗi rỗng nếu bạn thử và chuyển cho chúng một mảng '? Pass [] = 1', nhưng tôi không biết về UTF8 không hợp lệ, điều đó thật tuyệt. – rook

Các vấn đề liên quan