2011-09-02 25 views
6

Điều này đã được hỏi trước nhưng tôi cần 100% rõ ràng về vấn đề này vì điều rất quan trọng đối với tôi là phải làm đúng.Câu hỏi/Làm rõ PHP XSS

Tình huống: Hệ thống tin nhắn trên trang web. Người dùng nhập một tin nhắn vào một hộp văn bản, họ gửi biểu mẫu và nó được nhập vào cơ sở dữ liệu. Dữ liệu này sau đó có thể được gọi từ cơ sở dữ liệu và được hiển thị trong các thẻ <span> cho người dùng khác.

Tôi cần thực hiện các thủ tục bảo mật nào để ngăn chặn dữ liệu này độc hại? Tôi đã sử dụng mysql_real_escape_string để ngăn chặn bất kỳ tiêm và strip_tags có vẻ hữu ích nhưng tôi đã nghe rất nhiều tên khác được đề cập. Tôi cần sử dụng những gì để bảo vệ dữ liệu này vì nó chỉ được hiển thị trong các thẻ <span>?

Cảm ơn bạn.

+0

bản sao có thể có của [PHP: Làm thế nào để ngăn chặn hoàn toàn các cuộc tấn công XSS?] (Http://stackoverflow.com/questions/5934063/php-how-to-totally-prevent-xss-attacks) –

+0

Chỉ cần làm rõ, tôi 'm đánh dấu điều này như là một bản sao không phải vì nó là một câu hỏi xấu (nó không phải!) - Mọi người nên được điều này siêng năng –

+0

Điểm mấu chốt ở đây là luôn luôn khử trùng bất kỳ người dùng cung cấp dữ liệu không có vấn đề làm thế nào không đáng kể. – Jrod

Trả lời

3

Quan niệm sai lầm là bạn muốn thoát khỏi đầu vào. Bạn phải lọc đầu ra (và cơ sở dữ liệu cũng là đầu ra).

Điều này có nghĩa là khi biểu mẫu được gửi, bạn sử dụng mysql_real_escape_string() để gửi dữ liệu (đầu ra) tới cơ sở dữ liệu và bạn sử dụng htmlspecialchars() để xuất nội dung trên màn hình. Nguyên tắc tương tự áp dụng cho cụm từ thông dụng, nơi bạn sẽ sử dụng preg_quote(), v.v.

Bất kể dữ liệu đến từ đâu, bạn phải thoát khỏi nó trong ngữ cảnh bạn gửi nó đến.

Vì vậy, để ngăn chặn các cuộc tấn công XSS, bạn phải sử dụng htmlspecialchars()/htmlentities(). mysql_real_escape_string không liên quan gì đến XSS (nhưng bạn vẫn phải sử dụng nó khi bạn đang gửi dữ liệu đến cơ sở dữ liệu).

+0

Tôi biết mysql_real_escape_string là một chút không liên quan đến chủ đề này, nhưng tôi đã đề cập nó để tránh bất cứ ai nói "bạn phải làm điều đó quá!" :) Khi bạn đặt dấu gạch chéo giữa htmlspecialchars và htmlentities, bạn có đang sử dụng cả hai hoặc sử dụng cái này hay cái kia không? cái nào tốt hơn? Ngoài ra, preg_quote() là gì? Tôi không chắc chắn 100% chính xác ý bạn khi bạn nói khi bạn sử dụng nó trong một biểu thức chính quy (mặc dù tôi đã googled định nghĩa!) D: – James

+2

James, anh ta đề cập đến 'preg_quote' theo nghĩa là» sử dụng đúng công cụ cho đúng công việc «=» sử dụng chức năng thích hợp và được đề xuất để thoát đầu vào cho các miền/ngữ cảnh nhất định (htmlspecialchars cho html, mysqli_real_escape_string cho mysql dbs, các câu lệnh chuẩn bị cho bất kỳ db nào, preg_quote cho các biểu thức chính quy tương thích perl, escapeshellarg/escapeshellcmd cho các lệnh shell, vv) « – knittl

+0

+1 cho sự khác biệt giữa đầu vào và đầu ra. Nếu nó không phải là HTML, không xác nhận/lọc nó như vậy (sử dụng 'strip_tags()'). –

3

Sử dụng htmlspecialchars khi xuất trên trang HTML. Nó sẽ hiển thị dữ liệu giống như cách người dùng nhập vào (vì vậy người dùng có thể sử dụng một cái gì đó như <3 trong tin nhắn của họ mà không tước phần còn lại)

+0

và điều này một mình sẽ bảo vệ chống lại tất cả các loại XSS xem xét tôi chỉ đặt nội dung bên trong các thẻ '' chứ không phải bên trong các đối tượng html? Tôi chắc rằng tôi đã đọc ở nơi khác mà mọi người nói điều này là cũ và vô dụng? – James

+0

@James: 'htmlentities' là giải pháp thay thế tốt hơn nếu có trên hệ thống của bạn, nhưng cả hai đều hoạt động tốt. –

+0

James, điều này hoàn toàn an toàn khi bạn xuất văn bản bên trong ''. Nó không già và vô ích, nó được khuyến khích. ['htmlspecialchars'] (http://php.net/htmlspecialchars) cho đầu ra và [câu lệnh chuẩn bị] (http://php.net/mysqli_prepare)/[' mysqli_real_escape_string'] (http://php.net/mysqli_real_escape_string) – knittl

0

Vui lòng kiểm tra Bảng gian lận ngăn ngừa XSS của OWASP. Nó sẽ giải thích cách tránh XSS cho các ngữ cảnh khác nhau. Htmlentities nên làm công việc khi giữa các thẻ.