2009-02-20 19 views
15

Hiện tại, tôi áp dụng phương pháp 'ném mọi thứ vào tường và xem phương pháp nào ngăn chặn các vấn đề nói trên. Dưới đây là chức năng tôi đã hợp nhất với nhau:Cách tốt nhất để chống lại việc tiêm mysql và viết mã chéo trang

function madSafety($string) 
{ 

$string = mysql_real_escape_string($string); 
$string = stripslashes($string); 
$string = strip_tags($string); 
return $string; 

} 

Tuy nhiên, tôi tin rằng có cách tốt hơn để thực hiện việc này. Tôi đang sử dụng FILTER_ SANITIZE_STRING và điều này dường như không hoàn toàn an toàn.

Tôi đoán tôi đang hỏi, bạn sử dụng phương pháp nào và thành công như thế nào? Cảm ơn

+0

dupe: http://stackoverflow.com/questions/129677/whats-the-best-method-for-sanitizing-user-input-with-php – troelskn

+0

Cách tiếp cận này sai về nhiều khía cạnh! Tôi đã đăng câu trả lời dưới đây và đánh giá từng câu trả lời -1 cho tác giả của họ từ chối suy nghĩ. –

Trả lời

33

Chỉ cần thực hiện rất nhiều nội dung mà bạn không thực sự hiểu, sẽ không giúp bạn. Bạn cần phải hiểu những gì các cuộc tấn công tiêm là chính xác như thế nào và nơi bạn nên làm gì.

Trong điểm đạn:

  • Disable magic quotes. Họ là một giải pháp không đầy đủ, và họ lẫn lộn vấn đề.
  • Không bao giờ nhúng chuỗi trực tiếp trong SQL. Sử dụng tham số bị ràng buộc hoặc thoát (sử dụng mysql_real_escape_string).
  • Không unescape (ví dụ: stripslashes) khi bạn truy xuất dữ liệu từ cơ sở dữ liệu.
  • Khi bạn nhúng chuỗi bằng html (Ví dụ: khi bạn echo), bạn nên mặc định thoát khỏi chuỗi (Sử dụng htmlentities với ENT_QUOTES).
  • Nếu bạn cần nhúng chuỗi html vào html, bạn phải xem xét nguồn gốc của chuỗi. Nếu nó không tin cậy, bạn nên ống nó qua một bộ lọc. strip_tags là trong lý thuyết những gì bạn nên sử dụng, nhưng nó thiếu sót; Sử dụng HtmlPurifier để thay thế.

Xem thêm: What's the best method for sanitizing user input with PHP?

+0

Tuyệt vời - điều này là tốt hơn đáng kể so với phản hồi tôi đã viết, hiện đã bị bỏ qua. +1 –

+0

Lời nhắc thực sự tốt đẹp cho tất cả chúng ta :) +1 – itsols

2

Đừng! Sử dụng mysql_real_escape_string là đủ để bảo vệ bạn khỏi việc tiêm SQL và stropslashes bạn đang thực hiện sau khiến bạn dễ bị tấn công SQL. Nếu bạn thực sự muốn nó, đặt nó trước như trong:

function madSafety($string) 
{ 
    $string = stripslashes($string); 
    $string = strip_tags($string); 
    $string = mysql_real_escape_string($string); 
    return $string; 
} 

stripslashes là không thực sự hữu ích nếu bạn đang làm mysql_real_escape_string.

strip_tags bảo vệ chống lại việc tiêm HTML/XML, chứ không phải SQL.

Điều quan trọng cần lưu ý là bạn nên thoát chuỗi của mình khác nhau tùy thuộc vào việc sử dụng imediate bạn có cho nó.

Khi bạn đang thực hiện các yêu cầu MYSQL sử dụng mysql_real_escape_string. Khi bạn xuất các trang web, hãy sử dụng htmlentities. Để tạo liên kết web, hãy sử dụng urlencode

Như vartec đã lưu ý, nếu bạn có thể sử dụng trình giữ chỗ bằng mọi cách, hãy làm điều đó.

+5

Thực ra, mysql_real_escape_string cũng không hoàn toàn an toàn. Xem http://ilia.ws/archives/103-mysql_real_escape_string-versus-Prepared-Statements.html –

9

Cách tốt nhất để chống SQL injection là liên kết các biến, thay vì sau đó "tiêm" chúng vào chuỗi. http://www.php.net/manual/en/mysqli-stmt.bind-param.php

+0

Hãy cẩn thận với các thẻ cho phép - khá tốt bất kỳ thẻ nào có thể có JS được nhúng vào trong đó. –

+0

Ngoài ra - xem http://isisblogs.poly.edu/2008/08/16/php-strip_tags-not-a-complete-protection-against-xss/ –

+0

strip_tags là thiếu sót .. chuỗi thoát, hoặc nếu bạn thực sự cần để cho phép html, hãy sử dụng htmlpurifier – troelskn

0

Chủ đề này là rất sai!

Bạn KHÔNG nên lọc đầu vào của người dùng! Đó là thông tin đã được anh ta nhập vào. Bạn sẽ làm gì nếu tôi muốn mật khẩu của mình giống như: '"'>s3cr3t<script>alert()</script>

Lọc ký tự và để lại mật khẩu thay đổi, vì vậy tôi thậm chí không thể thành công trong lần đăng nhập đầu tiên? Thật tệ.

Giải pháp thích hợp là sử dụng báo cáo đã chuẩn bị hoặc mysql_real_escape_string() để tránh tiêm sql và sử dụng thoát khỏi ngữ cảnh của các ký tự để tránh mã html của bạn bị rối tung lên.

Để tôi nhắc bạn rằng web chỉ là một trong những cách bạn có thể thể hiện thông tin được người dùng nhập. Bạn có chấp nhận loại bỏ như vậy nếu một số phần mềm máy tính để bàn làm điều đó? Tôi hy vọng câu trả lời của bạn là KHÔNG và bạn sẽ hiểu tại sao điều này không đúng.

Lưu ý rằng trong các ngữ cảnh khác nhau, các ký tự khác nhau phải được thoát. Ví dụ, nếu bạn cần để hiển thị tên người dùng đầu tiên như một tooltip, bạn sẽ sử dụng một cái gì đó như:

<span title="{$user->firstName}">{$user->firstName}</span> 

Tuy nhiên, nếu người dùng đã đặt tên đầu tiên của mình để được như '"><script>window.document.location.href="http://google.com"</script> gì được bạn sẽ làm gì? Bỏ dấu ngoặc kép? Điều này sẽ rất sai! Thay vì làm điều này không có ý nghĩa, hãy xem xét thoát khỏi các dấu ngoặc kép trong khi hiển thị dữ liệu, không phải trong khi vẫn tồn tại nó!

Một ngữ cảnh khác bạn nên xem xét trong khi hiển thị chính giá trị đó. Hãy xem xét mã html đã sử dụng trước đây và tưởng tượng tên của người dùng giống như <textarea>. Điều này sẽ bọc tất cả các mã html sau đó vào yếu tố textarea này, do đó phá vỡ toàn bộ trang.

Một lần nữa - hãy xem xét thoát dữ liệu tùy thuộc vào ngữ cảnh bạn đang sử dụng nó!

P.S Không thực sự chắc chắn cách phản ứng trên các phiếu bầu phủ định đó. Bạn, mọi người, có thực sự đọc câu trả lời của tôi không?

+0

Thay vì xóa nhận xét của tôi, hãy cố gắng hiểu những gì tôi đã nói. Nếu người dùng có tên người dùng với các thẻ như vậy tôi sẽ không xóa các thẻ, tôi sẽ từ chối tên người dùng hoàn toàn và buộc họ phải đưa ra tên người dùng ít hơn, tha thứ cho tôi, ngu ngốc. Mật khẩu sẽ khác, chắc chắn, nhưng tên người dùng có '

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