2010-10-28 21 views
11

Tôi hiểu đúng cách để bảo vệ db khỏi việc tiêm SQL là bằng cách sử dụng các câu lệnh đã chuẩn bị. Tôi muốn hiểu cách câu lệnh chuẩn bị bảo vệ db của tôi.Trong PHP, PDO bảo vệ như thế nào khỏi việc tiêm SQL? Báo cáo chuẩn bị hoạt động như thế nào?

Đối với người mới bắt đầu, các câu được chuẩn bị giống như "truy vấn được tham số"?

Ví dụ: tôi dán bên dưới mã của mình để chèn người dùng mới vào bảng người dùng. Điều đó có an toàn không? PDO hoạt động như thế nào để đảm bảo an toàn? Có bất cứ điều gì cần phải được thực hiện để đảm bảo db từ tiêm?

Trong 'Class_DB.php':

class DB { 
private $dbHost; 
private $dbName; 
private $dbUser; 
private $dbPassword; 
function __construct($dbHost, $dbName, $dbUser, $dbPassword) { 
    $this->dbHost=$dbHost; 
    $this->dbName=$dbName; 
    $this->dbUser=$dbUser; 
    $this->dbPassword=$dbPassword; 
} 
function createConnexion() { 
    return new PDO("mysql:host=$this->dbHost;dbName=$this->dbName", $this->dbUser, $this->dbPassword); 
} 
} 

Trong 'DAO_User.php':

require_once('Class_DB.php'); 

class DAO_User { 
private $dbInstance; 
function __construct($dbInstance){ 
    $this->dbInstance=$dbInstance; 
} 
function createUser($user){ 
    $dbConnection=$this->dbInstance->createConnexion(); 
    $query=$dbConnection->prepare("INSERT INTO users (userName, hashedPassword, userEmail) VALUES (?,?,?)"); 
    $query->bindValue(1, $user->userName); 
    $query->bindValue(2, $user->hashedPassword); 
    $query->bindValue(3, $user->userEmail); 
    $query->execute(); 
} 
} 

Cảm ơn,

JDelage

+2

liên quan: http://stackoverflow.com/questions/134099/are-pdo-prepared-statements-sufficient-to-prevent-sql-injection –

+0

Cảm ơn Haim, phản ứng troelskn trả lời câu hỏi của tôi. – JDelage

+0

'được chuẩn bị báo cáo cùng một điều như" truy vấn tham số "? Ngoài ra, hãy để tôi chỉ cho bạn một vấn đề khác liên quan đến tiêm sql, được mô tả trong câu trả lời trước đây của tôi: http://stackoverflow.com/questions/2993027/in-php-when-submitting-strings-to-the-db-should- i-take-care-of-legal-characters/2995163 # 2995163 vì chúng tôi không chỉ chèn dữ liệu vào các truy vấn của chúng tôi, và các báo cáo đã chuẩn bị sẽ không giúp ích cho nó –

Trả lời

20

Ok, tôi tìm thấy câu trả lời cho câu hỏi của tôi trong câu hỏi có liên quan này: Are PDO prepared statements sufficient to prevent SQL injection?

Nhờ Haim cho trỏ Q này với tôi.

Về phi kỹ thuật, đây là cách chuẩn bị phát biểu bảo vệ từ tiêm:

Khi một truy vấn được gửi đến một cơ sở dữ liệu, nó thường được gửi như là một chuỗi. Công cụ db sẽ cố gắng phân tích cú pháp chuỗi và tách dữ liệu khỏi các hướng dẫn, dựa vào các dấu trích dẫn và cú pháp. Vì vậy, nếu bạn gửi "SELECT * WHERE 'người dùng gửi dữ liệu' EQUALS 'tên hàng bảng', động cơ sẽ có thể phân tích cú pháp hướng dẫn.

Nếu bạn cho phép người dùng nhập nội dung sẽ được gửi bên trong 'dữ liệu do người dùng gửi', thì họ có thể bao gồm trong nội dung này như '... "HOẶC NẾU 1 = 1 XÓA DATABASE'. phân tích cú pháp này và sẽ lấy phần trên làm hướng dẫn chứ không phải là một chuỗi vô nghĩa

Cách PDO hoạt động là nó gửi riêng hướng dẫn (chuẩn bị ("INSERT INTO ...)) và dữ liệu. Dữ liệu được gửi riêng, được hiểu rõ ràng chỉ là dữ liệu và dữ liệu. Công cụ db thậm chí không cố gắng phân tích nội dung của chuỗi dữ liệu để xem nó có chứa các chỉ lệnh hay không và bất kỳ mã snipet mã nào có khả năng gây hại không được xem xét.

+2

Tôi biết đây là câu trả lời cũ, nhưng điều này nên ở mọi mục sách văn bản cấp trên PHP và cơ sở dữ liệu. Rất rõ ràng và dễ hiểu! – MaDaHoPe

3

Dưới đây là cái nhìn hơi hạn chế của tôi trên vấn đề ...

Một câu lệnh chuẩn bị được biên dịch trên máy chủ DB với phần giữ chỗ cho đầu vào biến.

Khi bạn ràng buộc một tham số, bạn đang yêu cầu DB sử dụng giá trị nào khi bạn thực hiện truy vấn. Sau đó nó sẽ chuyển giá trị cho câu lệnh đã biên dịch.

Sự khác biệt giữa các tham số ràng buộc và tiêm chuỗi cũ đơn giản là với giá trị cũ, giá trị không được nội suy mà được gán. Trong quá trình thực hiện, DBMS truy cập một trình giữ chỗ và yêu cầu giá trị sử dụng. Bằng cách này, không có cơ hội của các ký tự trích dẫn hoặc các nasties khác lẻn theo cách của họ vào tuyên bố thực tế.

2

Không sử dụng báo cáo đã chuẩn bị, bạn không thể sử dụng trình giữ chỗ (?) Trong truy vấn của mình.

Thay vào đó, bạn sẽ cần bao gồm giá trị bạn muốn chèn trực tiếp vào câu lệnh SQL. Điều này sẽ dẫn đến một câu lệnh SQL khác nhau cho mỗi lần chèn (xấu cho hiệu suất) và nếu bạn không cẩn thận về những chuỗi mà bạn đưa vào câu lệnh, bạn cũng có thể kết thúc bằng một câu lệnh khác. SQL injection có thể xảy ra).

Tình huống này hơi giống với chức năng Javascript thực hiện một số mã cố định với thông số đầu vào biến, so với dán tham số đầu vào vào nguồn Javascript và sau đó đánh giá nó.

-1

nguồn của bạn được bảo mật khỏi vụ tấn công sqli.

ví dụ và không an toàn khi bạn chọn một người dùng từ cơ sở dữ liệu của mình.

// example: localhost/user.php?username=admin 

$getdata = $_GET['username']; 

$dbConnection=$this->dbInstance->createConnexion(); 
$query=$dbConnection->prepare("SELECT * FROM users WHERE username=".$getdata."); 

// PHP simple 
+0

Tôi tự hỏi ai sẽ upvote câu trả lời này mà hoàn toàn bỏ lỡ câu hỏi được hỏi ở đây –

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