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=1 SQL 注入的攻击。如果他们在地址栏中输入/posts.php?deletid=1 OR 1=1; ,它将删除数据库上的所有帖子。

在这个问题中:如何防止 PHP 中的 SQL 注入?,我意识到我需要使用 mysqli 语句,我试图让它工作但没有成功..

有人可以告诉我如何用mysqli防止这种情况吗?

4

4 回答 4

4

使用 MySQLi 和准备好的语句,您无需担心这一点,因为参数不能被替换1 OR 1=1(或者如果它作为参数值提供,则它被解释为字符串)。

于 2012-07-06T17:21:06.540 回答
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 回答
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(); 
?>

mysqli

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

首先是一件事:如果可以的话,最好不要使用 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 回答