2009-11-09 38 views
5

Tôi có một trường văn bản biểu mẫu chấp nhận url. Khi biểu mẫu được gửi, tôi chèn trường này vào cơ sở dữ liệu với đúng cách tiêm-sql-injection. Câu hỏi của tôi mặc dù là về xss.đầu vào là URL, cách bảo vệ nó khỏi xss

Trường nhập này là url và tôi cần hiển thị lại nó trên trang. Làm thế nào để bảo vệ nó khỏi xss trên đường vào cơ sở dữ liệu (tôi nghĩ không có gì là cần thiết vì tôi đã được chăm sóc tiêm sql) và trên đường trong số cơ sở dữ liệu?

Giả sử chúng ta có nó như thế này, tôi đơn giản hóa nó, và xin đừng lo lắng về việc tiêm sql. Tôi sẽ đi đâu sau đó?

$url = $_POST['url']; 

Cảm ơn

+1

Hãy chắc chắn và sử dụng các câu lệnh chuẩn bị để tránh việc tiêm SQL. http://php.net/manual/en/pdo.prepared-statements.php –

Trả lời

9

Giả sử này sẽ được đưa vào nội dung HTML (như giữa <body></body> hoặc giữa <div></div>), bạn cần phải mã hóa 5 ký tự XML đặc biệt (&, <, >, ", '), và OWASP đề xuất bao gồm dấu gạch chéo (/) là tốt. Xây dựng PHP, htmlentities() sẽ làm phần đầu tiên cho bạn, và một đơn giản str_replace() có thể làm dấu gạch chéo:

function makeHTMLSafe($string) { 
    $string = htmlentities($string, ENT_QUOTES, 'UTF-8'); 
    $string = str_replace('/', '&#x2F;', $string); 
    return $string; 
} 

Nếu, tuy nhiên, bạn sẽ đặt giá trị bị nhiễm vào một thuộc tính HTML, chẳng hạn như mệnh đề href= của <a, thì bạn sẽ cần phải mã hóa một nhóm ký tự khác ([dấu cách]% * + , - /; < =>^và |) -và bạn phải kích đúp quote HTML thuộc tính:

function makeHTMLAttributeSafe($string) { 
    $scaryCharacters = array(32, 37, 42, 43, 44, 45, 47, 59, 60, 61, 62, 94, 124); 
    $translationTable = array(); 
    foreach ($scaryCharacters as $num) { 
     $hex = str_pad(dechex($num), 2, '0', STR_PAD_LEFT); 
     $translationTable[chr($num)] = '&#x' . $hex . ';'; 
    } 

    $string = strtr($string, $translationTable); 
    return $string; 
} 

Mối quan tâm cuối cùng là bất hợp pháp tự UTF-8-khi giao cho một số trình duyệt, một chuỗi vô hình thành UTF-8 byte có thể thoát ra khỏi một thực thể HTML. Để bảo vệ chống lại điều này, chỉ cần đảm bảo rằng tất cả các ký tự UTF-8 bạn nhận được có giá trị:

function assertValidUTF8($string) { 
    if (strlen($string) AND !preg_match('/^.{1}/us', $string)) { 
     die; 
    } 

    return $string; 
} 

Các u sửa đổi trên mà biểu hiện thường xuyên làm cho nó một Unicode khớp regex. Bằng cách kết hợp một chararchter đơn lẻ, ., chúng tôi chắc chắn rằng toàn bộ chuỗi là Unicode hợp lệ.

Vì đây là tất cả phụ thuộc vào ngữ cảnh, tốt nhất nên thực hiện bất kỳ mã hóa nào trong thời điểm mới nhất — ngay trước khi trình bày đầu ra cho người dùng. Việc thực hành này cũng giúp bạn dễ dàng xem bất kỳ địa điểm nào bạn đã bỏ lỡ.

OWASP cung cấp nhiều thông tin về số XSS prevention cheat sheet của chúng tôi.

+0

Tôi chưa bao giờ nghe nói về bất kỳ biện pháp phòng ngừa đặc biệt nào được thực hiện với các thuộc tính html, các yếu tố văn bản bên trong. Bạn có bất kỳ tham khảo/giải thích cho điều đó? – troelskn

+2

Ah .. Để trả lời câu hỏi của riêng tôi, OWASP đề xuất điều này vì nó cần thiết * nếu các thuộc tính không được trích dẫn *. Thay vào đó, tôi khuyên bạn nên trích dẫn thuộc tính. – troelskn

+0

Đối với các ký tự mã hóa để đưa vào thuộc tính HTML, OWASP nói (thuộc tính nhấn mạnh) "Thuộc tính không được trích dẫn có thể được chia nhỏ với nhiều ký tự, ** bao gồm ** [dấu cách]% * +, - /; < = >^và |." . Vì vậy, chỉ cần mã hóa những điều này không đủ phải không? – Lode

1

Bạn cần mã hóa nó với htmlspecialchars trước khi hiển thị cho người dùng. Thông thường, điều này là đủ khi xử lý dữ liệu bên ngoài các thuộc tính thẻ > thẻ và/hoặc HTML.

1

Không cuộn bảo vệ XSS của riêng bạn, có quá nhiều cách có thể trượt trough (Tôi không thể tìm thấy liên kết đến một số XSS-demopage nhất định), nhưng số lượng khả năng là đáng kinh ngạc: Broken IMG- thẻ, thuộc tính lạ, v.v.).

Sử dụng thư viện hiện có như sseq-lib hoặc trích xuất một thư viện từ khung được thiết lập.

Cập nhật: Đây là the XSS-demopage.

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