Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 你的数据库安全吗?_Php_Mysql_Sql - Fatal编程技术网

Php 你的数据库安全吗?

Php 你的数据库安全吗?,php,mysql,sql,Php,Mysql,Sql,我知道你们中的一些人可能会结束这个问题,但我的问题来自你们和你们的答案。我正在阅读过去两个小时有关SQL注入和如何保护数据库的问答。我看到的大量网页和教程也是如此 我发现有一半的人声称prepare语句确实保护了你的数据库,而另外50人则声称不是 另一方面,我读到mysql\u real\u escape\u string做了这项工作,而其他人说不是 我的问题是相信谁 此外,这是一个适当的准备声明吗 $stmt = $dbh->prepare("SELECT phpro_user_id,

我知道你们中的一些人可能会结束这个问题,但我的问题来自你们和你们的答案。我正在阅读过去两个小时有关SQL注入和如何保护数据库的问答。我看到的大量网页和教程也是如此

我发现有一半的人声称prepare语句确实保护了你的数据库,而另外50人则声称不是

另一方面,我读到mysql\u real\u escape\u string做了这项工作,而其他人说不是

我的问题是相信谁

此外,这是一个适当的准备声明吗

$stmt = $dbh->prepare("SELECT phpro_user_id, phpro_username, phpro_password FROM phpro_users 
                    WHERE phpro_username = :phpro_username AND phpro_password = :phpro_password");

        /*** bind the parameters ***/
        $stmt->bindParam(':phpro_username', $phpro_username, PDO::PARAM_STR);
        $stmt->bindParam(':phpro_password', $phpro_password, PDO::PARAM_STR, 40);

        /*** execute the prepared statement ***/
        $stmt->execute();

事先准备好的声明不起作用。绑定参数保护语句(而不是整个数据库),只要所有不受信任的数据都通过参数传递,而不是插入到语句中。当人们使用预先准备好的语句时,他们几乎总是使用绑定参数,因此这两个名称经常混淆

  • 准备报表
  • 以变量作为附加参数的Run语句
  • mysql\u real\u escape\u string
    几乎总是执行此任务,但由于它在流程中添加了额外的步骤,因此更容易出现人为错误

  • Escape每个变量
  • 将变量连接到SQL语句中
  • 运行语句

  • 两者都有。准备好的语句将保护您不受SQL注入的影响,前提是您以正确的方式使用它们。例如,如果您仍在为表/列名插入变量,那么仅仅“使用”准备好的语句是没有帮助的

    $stmt = "SELECT * FROM $table WHERE $column = ?"; //not good...
    

    在某些情况下,无法使用准备好的语句。例如,当您必须动态生成
    IN()
    子句的内容时,如果您已动态选择逗号分隔的值进入
    IN()
    ,则无法执行
    WHERE col IN(?)
    。此外,如果需要在
    SELECT
    子句中动态生成列列表,则必须通过构建SQL字符串来实现


    底线是,两者都有各自的位置。准备好的语句对于预先确定的查询或必须多次执行的查询非常适合。当1)您必须具有最大的灵活性,2)您不要忘记转义所有输入时,转义动态SQL非常出色。

    这是一个很好的讨论。您的问题假设有一种技术可以“保护您的数据库”。事实上,没有一种技术是适合所有情况的。因此,您需要学习在不同情况下使用多种解决方案

    • 转义文字值
    • 准备好的查询中的参数占位符
    • 白名单地图
    请参阅我的演示文稿,其中详细介绍了防御SQL注入所需了解的一切


    在我的书中,我还介绍了SQL注入。

    Hi Mchl我用我正在使用的prepare语句更新了我的问题。这是一个正确的方法吗?+1-到目前为止最好的答案,尤其是“如果你以正确的方式使用它们的话”。这实际上有点用词不当。虽然您通常可以同时完成查询准备和参数化,但它们不是一回事。参数化确保了查询的完整性。出于这个原因,我投票支持昆汀的答案,是的。您正在为将放入语句中的所有值使用占位符。在MySQL中,表/列名(除其他外)不能用占位符代替。有些人使用变量插值来动态地创建这样的语句,却忘记了即使使用了预先准备好的语句,他们也应该转义这样的变量。戴姆斯:我同意,它们不是一回事,但人们通常认为它们实际上是一回事。还有一种神奇的想法,即“准备好的语句是SQL注入证明”,或者更糟糕的是“PDO是SQL注入证明”。+1:准备!=参数化。通常你可以同时做这两件事,但这并不意味着它们是同一件事。正是参数化使您能够确保查询的完整性。为什么您不能执行
    WHERE col IN(?)
    ?我们在这里做了很多,没有问题…@Fatal在什么RDBMS中?有关详细信息,您可以执行
    WHERE col IN(?,?)
    ,但不能将
    1,2,3,6,4,8,9
    值字符串绑定到单个
    Oracle数据库。是的,您必须调整?的计数以匹配您设置的值的数量。当然但这不是一个问题,不是吗?这不是一个真正的问题,但如果你想重用你准备好的语句,那就是一个麻烦。我还想补充一点,防止SQL注入只是“保护你的数据库”的一部分。保护数据库的安全还需要正确设置权限、设置密码字符串、锁定对服务器的访问,以及其他一些不会立即想到的因素。