0

重複の可能性:
PHPでSQLインジェクションを防ぐための最良の方法

私のウェブサイトでは、ユーザーは投稿を送信したり、投稿を削除したりできます。

/posts.php?deletid=X投稿を削除するには、Xがデータベース内の投稿のIDであるリンクをたどります(例:1)。

クリックすると、次のように実行されます。

if(isset($_GET['deleteid'])) { 
    $deleteid = $_GET['deleteid'];
        $sql = "DELETE from `posts` WHERE `id`=".mysql_real_escape_string($deleteid).";";
        $query = mysql_query($sql);
        header('Location: posts.php');
        exit(); 
}

問題は、1 =1SQLインジェクションに対して脆弱であるということです。アドレスバー/posts.php?deletid=1 OR 1=1; に入力すると、データベース上のすべての投稿が削除されます。

この質問では:PHPでSQLインジェクションを防ぐにはどうすればよいですか?、mysqliステートメントを使用する必要があることに気付き、それを機能させようとしましたが、成功しませんでした。

誰かがmysqliでこれを防ぐ方法を正確に教えてもらえますか?

4

4 に答える 4

4

mysql_real_escape_string有用な効果を得るには、値を引用符で囲む必要があります。

$sql = "DELETE from `posts` WHERE `id`='".mysql_real_escape_string($deleteid)."'";

mysql_real_escape_stringまたは、文字列を対象としたの代わりに、を試してくださいintval

于 2012-07-06T17:19:40.630 に答える
4

MySQLiとプリペアドステートメントを使用すると、パラメータをで置き換えることができないため、これについて心配する必要はありません1 OR 1=1(または、パラメータ値として提供されている場合は、文字列として解釈されます)。

于 2012-07-06T17:21:06.540 に答える
3

プリペアド ステートメントを使用することで、mysql_* 関数はすぐに廃止されます。これらの関数を使用して新しいコードを記述しないでください。コードをリファクタリングしてください。

PDO

<?php 
$db = new PDO("mysql:host=localhost;dbname=yourDB", $username, $password);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

/*** prepare the SQL statement ***/
$query = $db->prepare("DELETE from `posts` WHERE `id`=:id;");

/*** bind the paramaters ***/
$query->bindParam(':id', $deleteid, PDO::PARAM_INT);

/*** execute ***/
$query->execute();

header('Location: posts.php');
exit(); 
?>

みずい

<?php
$mysqli = new mysqli("localhost", "my_user", "my_password", "world");
/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}
/* create a prepared statement */
if ($stmt = $mysqli->prepare("DELETE from `posts` WHERE `id`=?")) {

    /* bind parameters for markers */
    $stmt->bind_param("i", $deleteid);

    /* execute query */
    $stmt->execute();

    /* close statement */
    $stmt->close();
}
/* close connection */
$mysqli->close();
header('Location: posts.php');
exit(); 
?>
于 2012-07-06T17:33:53.790 に答える
0

最初に 1 つ: 可能であれば、mysql_* を使用せずに、たとえば mysqli_* 関数または PDO を使用するのが賢明です。最初のものは古くなっているからです。そこ?では、文字列連結の代わりにプレースホルダー ( ) を使用できます。そこに自分自身を引用することを気にする必要はありません。

サンプル コードで最も簡単なオプションは、すべての数値を整数解析 (intval を使用) で実行することです。

if(isset($_GET['deleteid'])) { 
    $deleteid = $_GET['deleteid'];
            $sql = "DELETE from `posts` WHERE `id`=".intval($deleteid).";";
            $query = mysql_query($sql);
            header('Location: posts.php');
            exit(); 
}
于 2012-07-06T17:25:14.097 に答える