2009-02-13 24 views
8

Các cách tốt nhất để bảo vệ khỏi việc tiêm MySQL là gì? Những điểm yếu tôi nên tìm ra là gì?Bảo vệ chống tiêm của MySQL và các dấu hiệu dễ bị tổn thương bằng cách sử dụng PHP

Tôi biết nó là gì, nhưng tôi thực sự không biết mình có thể bị tổn thương như thế nào. Mặc dù tôi đã thực hiện (những gì tôi nghĩ là) các bước hướng tới bảo vệ bản thân và cơ sở dữ liệu của tôi.

Có cách nào chắc chắn ngăn người khác không?

BTW ... Tôi viết bằng PHP :)

Trả lời

1

Bạn phải khử trùng tất cả đầu vào. Cách bạn có thể làm điều này phụ thuộc vào sự yếu kém của chương trình và/hoặc khuôn khổ mà bạn đang làm việc.

chỉnh sửa:

Nếu bạn đang sử dụng php chức năng bạn đang tìm kiếm được mysql_real_escape_string ($ string). Bạn nên sử dụng nó trên tất cả mọi thứ bạn nhận được từ khách hàng mà nên đi vào cơ sở dữ liệu.

+0

xin lỗi vì không rõ ràng ... tôi sử dụng PHP – johnnietheblack

+2

Không bao giờ sử dụng thoát trừ khi bạn hoàn toàn không thể tránh được. Các chức năng thoát có thể, và đã được, lỗi, cho phép tiêm để trượt qua. Hầu như không thể cho những người triển khai DB tạo ra lỗi như vậy với các câu lệnh được tham số hóa, do đó, chúng đáng tin cậy hơn. –

+1

Có nói rằng, nếu bạn PHẢI sử dụng thoát (có nghĩa là mysqli_ * là ra khỏi câu hỏi vì lý do gì), mysql_real_escape_string thực sự là con đường để đi. –

1

Nếu bạn không sử dụng một khuôn khổ để cung cấp cho bạn với vệ sinh công cụ PHP có một escaper chuỗi được xây dựng trong, bạn nên bắt đầu ở đó. Bạn có thể tìm thấy tài liệu trên số within the PHP docs for mysql real escape string. Nếu bạn nhìn vào ví dụ ba, bạn sẽ có được một ý tưởng tốt về những điều cơ bản bạn có thể làm theo.

Một phương pháp khác mà tôi theo dõi là đảm bảo tôi truyền các biến thích hợp. Ví dụ nếu tôi mong đợi đầu vào từ người dùng để là một số nguyên, tôi sẽ làm như sau:

$age = (int)$age; 

Ngoài ra nếu một cột là vụ phải được giới hạn ở một hoặc hai giá trị (ví dụ một cột giới) hãy chắc chắn rằng bạn thực thi điều đó trong PHP của bạn trước khi đưa nó vào cơ sở dữ liệu.

0

Dấu hiệu cho thấy bạn có thể gặp sự cố sẽ lấy trực tiếp đầu vào của người dùng và đưa nó vào lệnh SQL của bạn.

Ví dụ: bạn yêu cầu tên người dùng của họ. Nếu bạn lấy nó và sau đó chỉ cần nói

"Chọn * Từ người dùng ở đâu Tên người dùng = '$ USERNAME';"

Sau đó, người dùng có thể thêm "JOE"; Bảng thả ... "v.v.

Trong perl bạn có thể nói cái gì đó như

my $sth2 = $dbh->prepare("Insert Into HostList (HostName,PollTime,Status) values (?,?,?);"); 
$sth2->execute($Hostname,$myDate,$Status); 

Các phương thức execute sau đó sẽ tìm kiếm khai thác như một ở trên và thoát khỏi nó đúng cách.

0

Tôi sử dụng hàm PHP này trên tất cả các đầu vào trước khi tôi cố gắng sử dụng nó trong bất kỳ mã nào (truy vấn MySQL, hiển thị dữ liệu, v.v ...). Nó có thể không hoàn thành, nhưng nó sẽ dừng tất cả các nỗ lực cơ bản tại hacking hệ thống:

//$linkID is the link ID of the connection to the MySQL database 
function clean_input($input) 
{ 
    GLOBAL $linkID; 
    if(get_magic_quotes_gpc()) 
    { 
     //Remove slashes that were used to escape characters in post. 
     $input = stripslashes($input); 
    } 
    //Remove ALL HTML tags to prevent XSS and abuse of the system. 
    $input = strip_tags($input); 
    //Escape the string for insertion into a MySQL query, and return it. 
    return mysql_real_escape_string($input,$linkID); 
} 
8

Tin tưởng không ai!

Vệ sinh tất cả đầu vào - filter_var() hoặc regexes hoặc in_array() giá trị hợp lệ hoặc chiến lược hỗn hợp tùy thuộc vào loại dữ liệu.

"Nhập" nghĩa là mọi nguồn đầu vào mà bạn không trực tiếp kiểm soát - không chỉ là biểu mẫu!

Vệ sinh mọi thứ bạn lấy lại từ $_GET, $_POST, $_SESSION, $_COOKIE - mọi thứ có thể có khả năng bị nhiễm độc.

Sử dụng chuẩn bị báo cáo

+0

$ _SESSION? Đó không phải là dữ liệu được lưu trữ, ghi vào và đọc từ trên máy chủ sao? –

+2

Yup. Và rất nhiều trang web được lưu trữ trên máy chủ được chia sẻ ... tin tưởng không ai. – PartialOrder

1

Điều này có vẻ như commonsense, nhưng tôi đã vấp lên trên đó một thời gian.

Có sự khác biệt giữa mã hóahtmlentities()thoátmysql_real_escape_string(). Tôi đã nghĩ về chúng như là khá hoán đổi cho nhau. Tuy nhiên không có ... như commonsense sẽ cho bạn biết. :) Thông thường tốt nhất là áp dụng cả hai, chẳng hạn như mã hóa đầu tiên, sau đó thoát.

Sau đó, khi kéo dữ liệu ra ngược lại quá trình, unescape (nếu cần) sau đó unencode. Lưu ý là cụ thể trong cách các bước được thực hiện (và đảo ngược) sẽ tiết kiệm rất nhiều đau đầu và đôi-thoát tai ương.

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