这是参数化查询的正确方法吗?还有其他办法吗?

时间:2019-06-25 08:39:18

标签: php html mysql sql-injection

我学会了如何在php中参数化查询,但是我只是想问一问,现在它是否可以完全免受sql注入或任何其他类型的攻击的侵害,如果不是,我可以做些什么来提高它的安全性呢? >

<?php
include 'db.php';
$name = "";
$pass = "";
if(isset($_POST['send'])) {
    $name = $_POST['name'];
    $sql_u = "SELECT * FROM users WHERE username='$name'";
    $res_u = $connection->query($sql_u);
    if (mysqli_num_rows($res_u) > 0) {
        echo "Sorry Username already taken";
    }
    else {
        $password = $_POST['pass'];
        $hpass = password_hash($password, PASSWORD_DEFAULT);
        $query=$connection->prepare("insert into users (username,password) values (?,?)");
        $query->bind_param('ss',$name,$hpass);
        if ($query->execute()) {
            $query->close();
            header('location:index.php');
        } else {
            header('location:not.php');
        }
    }
}

我想知道它们是否比仅参数化查询更为安全?

1 个答案:

答案 0 :(得分:2)

您正在使用INSERT语句的参数,但是跳过了使用SELECT语句的参数。在不参数化SELECT的情况下,您仍然存在SQL注入漏洞。将不受信任的内容与SQL结合使用时,在所有情况下都需要使用参数。

参数是在将动态内容作为SQL查询中的值组合时防止SQL注入的好方法。

您询问是否还有其他方法,因此,如果您要开始一个新的PHP项目,我建议您使用PDO。比Mysqli容易一点。在我看来,除非您要移植使用过时的Mysql PHP扩展名的旧版PHP应用程序,否则没有理由使用Mysqli。

这是使用PDO的外观:

$name = $_POST['name'];
$sql = "SELECT COUNT(*) FROM users WHERE username = ?";
$query = $connection->prepare($sql);
$query->execute([$name]);
$count = $query->fetchColumn();
if ($count > 0) {
    echo "Sorry Username already taken";
}
else {
    $password = $_POST['pass'];
    $hpass = password_hash($password, PASSWORD_DEFAULT);
    $sql = "insert into users (username, password) values (?, ?)";
    $query = $connection->prepare($sql);
    if ($query->execute([$name, $hpass])) {
        header('location:index.php');
    } else {
        header('location:not.php');
    }
}

我假设PDO连接是先前建立的,并且它是enabled with exceptions。如果不启用异常,则应检查每个prepare()execute()调用中的返回值,以确保没有错误。

Mysqli也是一样,您可以enable exceptions,因此您不必手动检查错误。

我还在示例中显示了我偏爱使用SELECT COUNT(*)而不是SELECT *的情况。在这种情况下,这可能是微不足道的优化,但是如果*引用了许多列或有许多行与username = $name匹配,则提取操作将需要从数据库传输更少的数据。