Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/285.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 如何预防MySQL睡眠注射?_Php_Mysql_Sql Injection - Fatal编程技术网

Php 如何预防MySQL睡眠注射?

Php 如何预防MySQL睡眠注射?,php,mysql,sql-injection,Php,Mysql,Sql Injection,最近,一个黑客试图用睡眠注射来减缓我的网站。尽管我们正在使用诸如mysql\u real\u escape\u string()之类的预防措施来覆盖大多数易受攻击的输入。我们通过查询字符串传递产品的id,它将命令设置为: $id = mysql_real_escape_string($_REQUEST['id']); $qry = "Select * from products where id = ".$id; 但黑客试图提供输入作为 ?id=3 and sleep(4) 而查询就变成了

最近,一个黑客试图用睡眠注射来减缓我的网站。尽管我们正在使用诸如
mysql\u real\u escape\u string()
之类的预防措施来覆盖大多数易受攻击的输入。我们通过查询字符串传递产品的id,它将命令设置为:

$id = mysql_real_escape_string($_REQUEST['id']);
$qry = "Select * from products where id = ".$id;
但黑客试图提供输入作为

?id=3 and sleep(4)
而查询就变成了

Select * from products where id = 3 and sleep(4);
虽然有一些可能的解决方案,如

  • 检查产品id是否为数字
  • 使用一些自定义函数从输入中删除单词sleep

  • 有没有其他方法可以阻止这一切?防止睡眠注入的最佳方法是什么?

    防止SQL注入的最佳方法是使用当前的技术。MySQL
    MySQL\uuz
    函数系列已被弃用,将在将来的版本中从PHP中删除

    您应该将准备好的语句与MySQLi或PDO一起使用

    这些技术使用预先准备好的语句和参数化查询。SQL语句由数据库服务器独立于任何参数进行解析。攻击者不可能注入恶意SQL

    您基本上有两个选项来实现这一点:

  • :

  • :

  • 发生的情况是,传递给
    prepare
    的SQL语句由数据库服务器解析和编译。通过指定参数(一个
    或一个命名的参数,如
    :name
    ),您可以告诉数据库引擎您要过滤的内容。然后,当您调用
    execute
    时,准备好的语句将与您指定的参数值相结合


    这里重要的一点是,参数值与已编译语句相结合,而不是与SQL字符串相结合。SQL注入的工作原理是,在脚本创建要发送到数据库的SQL时,诱使脚本包含恶意字符串。因此,通过将实际SQL与参数分开发送,您可以限制以意外结果结束的风险。使用预处理语句时发送的任何参数都将被视为字符串(尽管数据库引擎可能会进行一些优化,因此参数也可能最终成为数字)。

    您没有正确转义
    mysql\u real\u escape\u string
    用于正确转义SQL字符串语法,但您只是将值嵌入为裸值,而不是SQL字符串。你需要:

    $qry = "SELECT * FROM products WHERE id = '$id'";
    
    请注意查询中id周围的引号

    但是,如果id是数字,则将其转换为数字更为合理:

    $id = (int)$_GET['id'];
    

    您应该使用PDO或mysqli将查询转换为“准备好的语句”。

    这是一个错误的问题

    如何防止mysql注入?”必须这样做。睡觉或不睡觉-这不重要

    关于这个问题已经有很多答案了

    • 如果你想要一个规范的,那么
    • 如果你想了解它是如何工作的

    您是否意识到
    mysql\uu
    函数已被弃用,您不应该使用它们?将防止这种情况使用mysqli_uuu而不是mysql_u是的,查看准备好的语句不仅可以防止“睡眠注入”(我没听说过),还可以阻止所有类型的SQL注入。实际上,攻击者可能不想减慢你的网站速度,而是使用基于时间的盲查询攻击读取你数据库的所有内容。诀窍在于,他可以通过使用AND==“A”和SLEEP(5)之类的方法,尝试一个字节一个字节地猜测——如果页面需要+5秒,那么第一个假设是正确的。令人惊讶的是,整个数据库竟然可以这样读取(即使速度很慢)。我理解“准备好的语句”的概念,但你能解释一下为什么过滤
    $\u请求['id']
    作为防止传递不需要的参数的第一层保护是无效的吗?真正的问题是,“为什么要麻烦?”过滤是我们过去做这件事的方式,但时代在变化,我们已经前进了。对于一个数字值,你告诉我,它必须属于“准备好的声明”的范畴&我们都应该相信,有缺陷的现代接口方法在被揭露之前并不明显,这会更好吗?你真的认为纯粹的URL参数应该不加检查地传递吗?这似乎是一个有待解决的问题。这很好,尤其是说,“……而且更难实施。好吧,你几乎从未见过真正的二级攻击,因为通常更容易通过社会工程进入。”然后评论,“如果您的所有查询都已参数化,那么您也可以避免二次注入。一阶注入忘记了用户数据是不可信的。二阶注入忘记了数据库数据是不可信的(因为它最初来自用户)。“你不觉得这很重要吗?嘿,伙计们,戈登是绝对正确的。如果您认为为SQL转义数据仅仅是一种安全措施,那么您会大吃一惊。在将数据用于应该转义的上下文之前,不要转义数据。否则,您只会将数据弄得一团糟!此外,如果您正确构建系统并使用准备好的查询,则永远不可能进行二阶攻击。你可能认为这不是问题。。。但事实确实如此。即使您不认为这是一个安全问题,也要记住,字段中的一个简单引号稍后会使您出错。也许不是恶意的,但至少是坏的。+1指出了mysql的正确用法。\u real\u escape\u string@deceze:谢谢你的回答。我之所以接受它,是因为它的第一部分意味着正确使用mysql\u real\u escape\u string()对我的问题来说更相对、更快速。值得补充的是,
    mysql\u*
    函数已经弃用,不应该再使用了。另外,需要注意的是,查询需要单引号才能正常工作。如果在查询字符串中使用双引号进行排序,则该值将使{mysql\u real\u escape\u string()}无用!这就解决了问题。
    $qry = "SELECT * FROM products WHERE id = '$id'";
    
    $id = (int)$_GET['id'];