5

私が作成したソフトウェアの展開の自動化に取り組んでおり、新しいアカウント用に新しい mysql データベースを生成できるようにする必要があります。ただし、入力のサニタイズに関しては懸念があります。

私は PDO を使用しています。ただし、「CREATE DATABASE」では準備済みステートメントを使用できないようです。そこで、PDO::quot; も使ってみました。ただし、新しく作成したデータベース名は一重引用符で囲まれています (世界の終わりではありませんが、それでも避けたいと思います)。

これを準備済みステートメントで動作させる方法はありますか? そうでない場合、SQL インジェクション攻撃からできるだけ身を守るにはどうすればよいですか? 私の他の唯一のアイデアは、文字の小さなホワイトリストを許可することです.

ありがとう!

4

1 に答える 1

2

サニタイズされた入力を渡すことができるストアド プロシージャを作成する必要があります (私の例を使用するには、データベース名や正しいユーザーなどの変数を変更してパスなどを実行する必要があります)。もちろんデータベース)

例:

<?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;
    }
}

ストアド プロシージャ:

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 ;

私たちの場合、ステートメントは変数では機能しないため、 PREPAREにSQL ステートメントを作成し、それを単にEXECUTEします。最後に、ストアド プロシージャを実行します。それは、パラメータを使用してバインドできることです。CREATE DATABASE <our database>;CREATE DATABASECALL dbcreator('<dbname>')CALL dbcreator(:dbname)

ご覧のとおり、この方法では、データベースの作成中に pdo を介して安全にパラメーターをバインドできます。それでも、検索と識別を容易にするために、作成するすべてのデータベースに短い固定文字列をプレフィックスとして付けることは悪い考えではないかもしれません。ストアド プロシージャでは、dbname は64 文字に制限されています。これが mysql の現在の制限であるためです。

于 2012-06-17T00:23:48.413 に答える