2013-03-18 25 views
12

Tôi khá mới đối với PDO và tự hỏi liệu truy vấn của tôi dưới đây có an toàn với SQL injection hay không. Tôi sẽ sử dụng phương pháp này trên toàn trang nếu có.Truy vấn PDO của tôi có an toàn khỏi việc tiêm SQL không

// make connection to DB 
$db = new PDO('mysql:host='.$dateBaseHost.';dbname='.$dateBaseName, $dateBaseUsername, $dateBasePassword); 
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 


//simple query and binding with results 
$query = $db->prepare(" SELECT * FROM `profile` WHERE `fullname` = :fullname "); 

$search = (isset($_GET['search']) === true) ? $_GET['search'] : '' ; // ? : shorthand for if else 

// bind parameters - avoids SQL injection 
$query->bindValue(':fullname', $search); 

//try... if not catch exception 
try { 
    // run the query 
    $query->execute(); 

    $rows = $query->fetchAll(PDO::FETCH_ASSOC); 
    echo '<pre>', print_r($rows, true),'</pre>'; 
} 
catch (PDOException $e){ 
    sendErrorMail($e->getMessage(), $e->getFile(), $e->getLine()); 
} 
+0

Miễn là bạn đang sử dụng parametrized, truy vấn Truy vấn của bạn an toàn. – Rohitink

+0

Có. Bạn đang sử dụng tham số hóa, thao tác này sẽ tự động thoát cần thiết. Công cụ tuyệt vời! – halfer

Trả lời

8

Có - truy vấn được tham số hóa được an toàn khi tiêm khi được sử dụng theo cách này.

+0

Nó chỉ an toàn chống lại các cuộc tấn công cơ bản ... –

5

Miễn là bạn sử dụng báo cáo đã chuẩn bị đúng cách, bạn sẽ an toàn khi tiêm. nhưng ngay sau khi bạn DIRECTLY chèn bất kỳ dữ liệu ngoài nào vào truy vấn, ngay cả khi đó là một tuyên bố đã chuẩn bị, ví dụ:

INSERT INTO $table VALUES (:param) 

bạn dễ bị tổn thương - $table có thể bị hủy trong trường hợp này, mặc dù bạn đang sử dụng câu lệnh đã chuẩn bị.

Bất cứ ai nói với bạn chỉ cần chuyển mysql-> PDO hoặc mysqli sẽ làm cho bạn an toàn hơn là phẳng ra WRONG. Bạn có thể dễ bị tấn công bằng cách tiêm với thư viện.

0

có, nó là khá an toàn nhưng toàn bộ kịch bản có thể được cải thiện:

if (isset($_GET['search']) { 
    // make connection to DB 
    $opt = array(
     PDO::ATTR_ERRMODE   => PDO::ERRMODE_EXCEPTION, 
     PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC 
    ); 
    $dsn = "mysql:host=$dateBaseHost;dbname=$dateBaseName;charset=$dateBaseCharset"; 
    $db = new PDO($dsn, $dateBaseUsername, $dateBasePassword, $opt); 

    //simple query and binding with results 
    $query = $db->prepare("SELECT * FROM profile WHERE fullname = ?"); 
    $query->execute(array($_GET['search'])); 
    $rows = $query->fetchAll(); 
    echo '<pre>', print_r($rows, true),'</pre>'; 
} 
  • bạn cần phải thiết lập errmode như một tùy chọn kết nối
  • không bao giờ sử dụng try..catch để xử lý thông báo lỗi. nếu bạn muốn có một email trên mỗi lỗi (mà chỉ là điên), bạn phải thiết lập my_exception handler() cho việc này.
  • thiết lập tìm kiếm để chuỗi rỗng không thực hiện bất kỳ cảm giác
  • kết nối với PDO nên chuyển tập tin rất riêng biệt (không hiển thị)
  • charset đã được thiết lập trong DSN
+1

tại sao bạn nên ** không bao giờ ** sử dụng khối 'try ... catch' để xử lý lỗi? họ có nó trong tất cả các tài liệu ..? –

+0

Tôi naver nói "lỗi" nhưng "thông báo lỗi". Có, họ có tất cả sai –

+0

Tôi muốn biết suy nghĩ của bạn về câu trả lời và giải pháp của Marc B. –

3

Bạn cũng nên

$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); 

Theo mặc định nó sử dụng chế độ mô phỏng, mà chỉ đơn thuần là làm những gì mysql_real_escape_string làm. Trong một số trường hợp cạnh, bạn vẫn dễ bị tấn công SQL injection.

+0

quá cạnh Tôi muốn nói –

+0

@YourCommonSense: nhưng vẫn quan trọng, hãy xem câu trả lời của hai người, đặc biệt là câu trả lời của câu hỏi này (http://stackoverflow.com/a/12202218/258127). –

+0

Điều này thực sự làm gì? – user2183216

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