12

私は PDO にかなり慣れていないので、以下のクエリが SQL インジェクションから安全かどうか疑問に思っています。もしそうなら、私はサイト全体でこの方法を使用します。

    // make connection to DB
$db = new PDO('mysql:host='.$dateBaseHost.';dbname='.$dateBaseName, $dateBaseUsername, $dateBasePassword);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);


//simple query and binding with results
$query = $db->prepare(" SELECT * FROM `profile` WHERE `fullname` = :fullname ");

$search = (isset($_GET['search']) === true) ? $_GET['search'] : '' ; // ? : shorthand for if else

// bind parameters - avoids SQL injection
$query->bindValue(':fullname', $search);

//try... if not catch exception
try {
    // run the query
    $query->execute();

    $rows = $query->fetchAll(PDO::FETCH_ASSOC);
    echo '<pre>', print_r($rows, true),'</pre>';
}
catch (PDOException $e){
    sendErrorMail($e->getMessage(), $e->getFile(), $e->getLine());
}
4

4 に答える 4

8

はい - パラメータ化されたクエリは、この方法で使用するとインジェクションから安全です。

于 2013-03-18T16:36:04.427 に答える
5

準備済みステートメントを適切に使用している限り、インジェクションの心配はありません。ただし、それ以外の場合は準備済みのステートメントであっても、外部データをクエリに直接挿入するとすぐに、たとえば

INSERT INTO $table VALUES (:param)

あなたは脆弱です-$tableこの場合、準備されたステートメントを使用していても、破壊される可能性があります.

単にmysql- >PDO または mysqli を切り替えるだけで安全になると言う人は、完全に間違っています。どちらのライブラリでも、インジェクション攻撃に対して同じように脆弱になる可能性があります。

于 2013-03-18T16:38:18.313 に答える
3

あなたもすべきです

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

デフォルトでは、エミュレート モードを使用しますmysql_real_escape_string。一部のエッジ ケースでは、依然として SQL インジェクションに対して脆弱です。

于 2013-03-18T16:43:59.400 に答える
0

はい、かなり安全ですが、スクリプト全体を改善することができます:

if (isset($_GET['search']) {
    // make connection to DB
    $opt = array(
        PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
        PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
    );
    $dsn = "mysql:host=$dateBaseHost;dbname=$dateBaseName;charset=$dateBaseCharset";
    $db  = new PDO($dsn, $dateBaseUsername, $dateBasePassword, $opt);

    //simple query and binding with results
    $query = $db->prepare("SELECT * FROM profile WHERE fullname = ?");
    $query->execute(array($_GET['search']));
    $rows = $query->fetchAll();
    echo '<pre>', print_r($rows, true),'</pre>';
}
  • 接続オプションとして errmode を設定する必要があります
  • エラー メッセージの処理に try..catch を使用しないでください。エラーごとに電子メールを受け取りたい場合 (これはクレイジーです)、これを設定する必要がありますmy_exception handler()
  • 検索を空の文字列に設定しても意味がありません
  • PDOへの接続は別のファイルに移動する必要があります(表示されていません)
  • charset は DSN で設定する必要があります
于 2013-03-18T16:39:33.303 に答える