2011-01-20 28 views
6

Với đoạn mã sau đây, tôi có cần phải thoát và vệ sinh $city?Tôi có cần phải khử trùng đầu vào nếu sử dụng các truy vấn PHP/MySQL chuẩn bị không?

<?php 
$mysqli = new mysqli("localhost", "my_user", "my_password", "world"); 

/* check connection */ 
if (mysqli_connect_errno()) { 
    printf("Connect failed: %s\n", mysqli_connect_error()); 
    exit(); 
} 

$city = "Amersfoort"; 

/* create a prepared statement */ 
if ($stmt = $mysqli->prepare("SELECT District FROM City WHERE Name=?")) { 

    /* bind parameters for markers */ 
    $stmt->bind_param("s", $city); 

    /* execute query */ 
    $stmt->execute(); 

    /* bind result variables */ 
    $stmt->bind_result($district); 

    /* fetch value */ 
    $stmt->fetch(); 

    printf("%s is in district %s\n", $city, $district); 

    /* close statement */ 
    $stmt->close(); 
} 

/* close connection */ 
$mysqli->close(); 
?> 

Bạn có cần vệ sinh mọi đầu vào khi sử dụng truy vấn đã chuẩn bị không?

Trả lời

9

Không có bạn không phải thoát khỏi nó hoặc khử trùng nó để tiêm bảo vệ. Đối với những ứng dụng cụ thể khác, bạn có thể khử trùng nó.

Tôi đã có một câu hỏi tương tự một khi trở lại:

mysqli_stmt_bind_param SQL Injection

8

@Gary: Bạn sao chép rằng đoạn mã trực tiếp từ hướng dẫn tại php.net về mysqli :: chuẩn bị. Trên cùng một trang đó là văn bản sau:

"Mục đích của các câu lệnh chuẩn bị là không bao gồm dữ liệu trong các câu lệnh SQL của bạn. Bao gồm cả chúng trong câu lệnh SQL của bạn KHÔNG an toàn. mã dễ đọc hơn) và không dễ bị tiêm SQL. "

Câu trả lời cho câu hỏi của bạn là gì;)

+4

Cây cối bị cản trở trên gỗ. ;) –

+0

Có, nhưng các câu lệnh chuẩn bị thường yêu cầu nhiều tài nguyên hơn ở cả lớp ứng dụng và lớp dữ liệu - hãy cẩn thận khi bạn thấy ai đó nói, "luôn luôn sử dụng câu lệnh đã chuẩn bị". – Jmoney38

+0

@ Jmoney38 Phát hiện ra, tôi nghĩ mọi giải pháp nên được suy nghĩ cẩn thận thay vì chỉ chọn nó vì nó có vẻ là thực tế phổ biến. – Sander

1

Ngoài ra. Ngoài ra.

Các biểu đồ được chuẩn bị, nếu được sử dụng đúng cách, gần như hoàn toàn giảm thiểu các tai họa SQL injection. Tuy nhiên, bạn nên định dạng/khử trùng dữ liệu đầu vào nếu thích hợp. Làm sạch đầu vào không phải là một tính năng bảo mật, nhưng được khuyến khích cho sự vững mạnh và khả năng sử dụng. Trong trường hợp của $ thành phố của bạn, bạn có thể muốn loại bỏ tất cả các ký tự không phải chữ:

$city = trim(preg_replace("/[^\w-]+/", " ", $city)); 

nào một lần nữa: không thay thế cơ sở dữ liệu thoát hoặc chuẩn bị phát biểu, nhưng đảm bảo dữ liệu thống nhất để làm việc với.

+0

Nhưng đó không phải là khử trùng (loại bỏ bất kỳ ký tự bất hợp pháp nào khỏi dữ liệu.), Nhưng xác nhận. Chúng là 2 thứ khác nhau. Bạn phải luôn xác thực dữ liệu của mình ngay cả với các câu lệnh đã được chuẩn bị. – viery365

0

Tôi nhận thấy câu hỏi này rất cũ. Tôi tình cờ gặp nó trong khi tìm kiếm cùng một thông tin. Tôi bình luận về câu trả lời của Sander nhưng tôi chưa có đủ tiếng để bình luận. Sander nói rằng bạn không cần phải khử trùng, nhưng tại http://www.w3schools.com/php/php_mysql_prepared_statements.asp (và tôi nhận ra w3schools không phải luôn luôn là một nguồn hoàn toàn cập nhật và chính xác của thông tin, nhưng tôi tìm thấy nó phép thuật ra một cách hợp lý, dễ dàng để hiểu cách), họ nói "Lưu ý: Nếu chúng tôi muốn chèn bất kỳ dữ liệu nào từ các nguồn bên ngoài (như đầu vào của người dùng), điều quan trọng là dữ liệu được vệ sinh và xác thực".

Vì vậy, có vẻ như là khi sử dụng biểu mẫu và chấp nhận đầu vào của người dùng, bạn nên khử trùng.

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