2

訪問者の入力をデータベースに挿入しようとしています。
これは機能しますが、SQL インジェクションを防ぐにはこれで十分でしょうか?

<?php
$db_host = "localhost";
$db_name = "db_qadenza";
$db_user = "root";

$odb = new PDO ("mysql:host=" . $db_host . ";dbname=" . $db_name, $db_user);

if(isset($_POST['Submit']))
{
$user = $_POST['user'];
$pass = $_POST['pass'];
$mail = $_POST['mail'];
$confirm_key=md5(uniqid(rand()));

$q = "INSERT INTO members (user, pass, mail, confirm_key)
VALUES(:user, :pass, :mail, :confirm_key);";

$query = $odb->prepare($q);
$results = $query->execute(array(
":user"=>$user,
":pass"=>$pass,
":mail"=>$mail,
":confirm_key"=>$confirm_key,
));

exit();
}
?>
4

3 に答える 3

4

コードには 2 つの問題があります。

  1. エミュレートされた準備済みステートメントを使用しています。これは、PDO_MYSQL ドライバーのデフォルトの動作です。これを回避するには、次を追加する必要があります。

    $odb->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
    

    DB との通信用の文字セットが欠落しているため、コードがインジェクションに対してオープンになる可能性があります。接続を確立するには、次を使用する必要があります。

    $odb = new \PDO('mysql:host=localhost;dbname=******;charset=UTF-8', 
                    'user', 'pass');
    
  2. パスワードをハッシュする方法は安全ではありません (または、実際には存在しません)。代わりに、またはPBKDF2crypt()と一緒に関数を使用し、パスワードごとに異なるソルトを使用する必要があります。CRYPT_BLOWFISH

また、bindParam()メソッドを使用して名前付きパラメーターのaluseを設定することを検討することもできます。これらを設定すると値がexecute()としてバインドされるためです。PDO::PARAM_STR

于 2012-08-04T05:02:55.907 に答える
2

はい。prepare($query)メソッドは、ユーザー定義の値が渡された変数として入力されている限り、SQL インジェクションが発生しないことを保証します。

リンクされたページから:

アプリケーションがプリペアード ステートメントのみを使用する場合、開発者は SQL インジェクションが発生しないことを確認できます [...]

于 2012-08-04T04:54:31.883 に答える
1

はい。私にはうまく見えます。

必要に応じて、追加の mysql ユーザーを作成して、SQL インジェクションが発生した場合に範囲を制限することもできます。現在、 として接続していrootます。

また、salt + BCrypt などのパスワード ハッシュ スキームの使用も検討してください。

于 2012-08-04T04:56:39.197 に答える