2012-06-16 26 views
5

Tôi đang làm việc để tự động triển khai một phần mềm tôi đã viết và cần có khả năng tạo cơ sở dữ liệu mysql mới cho tài khoản mới. Tuy nhiên, tôi đang lo ngại khi làm vệ sinh đầu vào.Tạo cơ sở dữ liệu mới từ đầu vào có khả năng không an toàn thông qua PDO và mysql

Tôi đang sử dụng PDO; tuy nhiên, dường như bạn không thể sử dụng câu lệnh đã được chuẩn bị với 'TẠO LẠI CƠ SỞ'. Vì vậy, tôi cũng đã thử sử dụng PDO :: quote; tuy nhiên, sau đó các tên cơ sở dữ liệu mới được tạo của tôi được bao quanh bởi các dấu nháy đơn (không phải là kết thúc của thế giới, nhưng tôi vẫn muốn tránh điều đó).

Có cách nào để làm điều này để làm việc với các báo cáo đã chuẩn bị không? Nếu không, tôi có thể làm gì để bảo vệ bản thân mình càng nhiều càng tốt khỏi các cuộc tấn công tiêm sql? Ý tưởng duy nhất khác của tôi là có một danh sách trắng cho phép.

Cảm ơn!

+2

Danh sách trắng có lẽ là cách tốt nhất để đi - cũng như một số công cụ lưu trữ mySQL sẽ tạo các thư mục và tệp chứa tên cơ sở dữ liệu. –

Trả lời

2

bạn sẽ cần phải viết stored procedure mà sau đó bạn có thể chuyển đầu vào đã được vệ sinh (để sử dụng ví dụ của mình, bạn cần phải thay đổi một số biến như tên cơ sở dữ liệu và người dùng và thông tin chính xác) nó chạy trên cơ sở dữ liệu của bạn tất nhiên)

dụ:

<?php 
$dsn = 'mysql:dbname=scratch;host=127.0.0.1'; 
$user = 'root'; 
$password = ''; 

try { 
    $dbh = new PDO($dsn, $user, $password); 
} catch (PDOException $e) { 
    echo 'Connection failed: ' . $e->getMessage(); 
} 

$dbname = 'brand_new_db'; 

$statement = $dbh->prepare("CALL dbcreator(:db)"); 
$statement->bindParam(':db',$dbname); 

if(!$statement->execute()){ 
    print_r($statement->errorInfo()); 
} 
else { 
    foreach($dbh->query('SHOW DATABASES')->fetchAll() as $row){ 
     print "$row[0]" . PHP_EOL; 
    } 
} 

thủ tục lưu trữ:

DELIMITER $$ 

DROP PROCEDURE IF EXISTS `scratch`.`dbcreator` $$ 
CREATE DEFINER=`root`@`localhost` PROCEDURE `dbcreator`(IN dbname VARCHAR(64)) 
BEGIN 

SET @db = dbname; 
SET @statement = CONCAT('CREATE DATABASE ',@db); 
PREPARE prepared_statement FROM @statement; 
EXECUTE prepared_statement; 

END $$ 

DELIMITER ; 

Y tạo một câu lệnh SQL tới PREPARE, trong trường hợp của chúng tôi CREATE DATABASE <our database>; vì câu lệnh CREATE DATABASE sẽ không hoạt động với một biến, và sau đó bạn chỉ cần EXECUTE nó. Cuối cùng, bạn thực hiện CALL dbcreator('<dbname>') để thực hiện quy trình được lưu trữ. Đó là CALL dbcreator(:dbname), bạn có thể sử dụng và ràng buộc các tham số.

Như bạn có thể thấy, bằng cách này bạn vẫn có thể ràng buộc các thông số của mình một cách an toàn thông qua pdo trong khi tạo cơ sở dữ liệu. Tuy nhiên, có thể không phải là một ý tưởng tồi để tạo tiền tố cho tất cả cơ sở dữ liệu bạn tạo bằng một chuỗi cố định ngắn để dễ dàng tra cứu và phân biệt đối xử. Trong dbname thủ tục lưu sẵn là limited to 64 characters vì đó là giới hạn hiện tại của mysql

+0

Cảm ơn! Điều đó sẽ làm các trick. Tôi sẽ vẫn có thể kết hợp điều này với một danh sách trắng do các yêu cầu khác và để lọc ra rác, nhưng bằng cách sử dụng báo cáo chuẩn bị chỉ cho phép tôi ngủ tốt hơn một chút. – user1234814

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