Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/solr/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 通过PDO和mysql从潜在的不安全输入创建新数据库_Php_Mysql_Pdo_Prepared Statement - Fatal编程技术网

Php 通过PDO和mysql从潜在的不安全输入创建新数据库

Php 通过PDO和mysql从潜在的不安全输入创建新数据库,php,mysql,pdo,prepared-statement,Php,Mysql,Pdo,Prepared Statement,我正在致力于自动化我所编写的一个软件的部署,需要能够为新帐户生成新的mysql数据库。然而,当涉及到清理输入时,我有一些担心 我正在使用PDO;但是,显然不能将准备好的语句与“createdatabase”一起使用。因此,我也尝试使用PDO::quote;然而,我新创建的数据库名称被单引号包围(不是世界末日,但我仍然希望避免这种情况) 有什么方法可以让这项工作与准备好的声明一起进行吗?如果没有,我可以做些什么来尽可能地保护自己免受sql注入攻击?我唯一的另一个想法是允许有一个小的字符白名单 谢谢

我正在致力于自动化我所编写的一个软件的部署,需要能够为新帐户生成新的mysql数据库。然而,当涉及到清理输入时,我有一些担心

我正在使用PDO;但是,显然不能将准备好的语句与“createdatabase”一起使用。因此,我也尝试使用PDO::quote;然而,我新创建的数据库名称被单引号包围(不是世界末日,但我仍然希望避免这种情况)

有什么方法可以让这项工作与准备好的声明一起进行吗?如果没有,我可以做些什么来尽可能地保护自己免受sql注入攻击?我唯一的另一个想法是允许有一个小的字符白名单

谢谢

您需要编写一个文件,然后将经过消毒的输入传递给该文件 (使用我的示例,您需要更改一些变量,如数据库名称和正确的用户和密码等,以使其在您的数据库上运行)

例如:

<?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;
    }
}
在我们的例子中,创建一个SQL语句来创建数据库因为
CREATE DATABASE
语句不能与变量一起使用,所以您只需使用它即可。最后,调用dbcreator(“”)执行存储过程。就是调用dbcreator(:dbname),您可以使用它并将参数绑定到它


如您所见,通过这种方式,您仍然可以在创建数据库时通过pdo安全地绑定参数。不过,为便于查找和识别,在您创建的所有数据库前面加上一些简短的固定字符串可能不是一个坏主意。在存储过程中,dbname是因为这是mysql当前的限制

白名单可能是最好的选择-同时,一些mysql存储引擎会创建包含数据库名称的文件夹和文件。谢谢!这应该能奏效。由于其他要求,我仍然可能会将其与白名单结合起来,并过滤掉垃圾,但使用预先准备好的语句只会让我睡得好一点。
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 ;