准备好的声明是否可以保护我免受数据库中的垃

问题描述 投票:1回答:4

基本上我在网上阅读了一些文章之后开始使用预备语句,这些文章说这是防止sql注入的简单方法。跳转到我的场景,我有一个logExit函数,它将访问者来自我网站的页面和他离开我网站后的页面插入数据库。

public function logExit($url){
    $HTTP_REFERER = ($_SERVER['HTTP_REFERER'] ? $_SERVER['HTTP_REFERER'] : '');    
    $REMOTE_ADDR = ($_SERVER['REMOTE_ADDR'] ? $_SERVER['REMOTE_ADDR'] : '');

    $params = array(
        $REMOTE_ADDR,
        $HTTP_REFERER,
        $url
    );

    // custom query function ~ prepare/execute
    $this->query("
        INSERT INTO exits(ip, url_in, url_out) VALUES (?, ?, ?)
    ", "sss", $params);
}

问题是,今天当我登录管理面板检查我今天有多少访问者以及他们从我的网站离开了哪里时,我收到了大量警报。当我检查我的数据库时,我有13500个从相同的IP退出到不同的页面,但问题来自url_in字段,这里有一些例子:

     ip    |               url_in                |    url_out    |
-----------+-------------------------------------+---------------|
  xx.xx.xx |'"></a><script>alert(11779)</script> | xxxxxxxxxxxxx |
-----------+-------------------------------------+---------------|
  xx.xx.xx |            ,alert(11774),           | xxxxxxxxxxxxx |
-----------|-------------------------------------|---------------|
  xx.xx.xx |                %c0%a7               | xxxxxxxxxxxxx |
-----------|-------------------------------------|---------------|
  xx.xx.xx |                 %2527               | xxxxxxxxxxxxx |
-----------+-------------------------------------+---------------|

HTTP_REFERER = url_in

$ url = url_out

所以这似乎很奇怪,因为据我所知HTTP_REFERER应该是一个URL。这个混乱怎么进入我的数据库以及如何防止它?

谢谢

PS。托管公司向我展示了这个日志,这是什么意思?

access-logs/my-example-website.com:xxx.xxx.xxx.xx - - [21/Dec/2017:18:59:59 +0200] "GET /mode.php?admin_mode=1&referer=javascript:alert(16555) HTTP/1.1" 404 - "-" "Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko"
php mysql sql-injection
4个回答
7
投票

这是按设计工作的,您可以免受SQL注入问题的影响。这里的关键是SQL注入攻击只是one vector of many

为了安全地使用该内容,您必须正确地将其转义为使用它的上下文。如果您将其显示为HTML,这意味着使用htmlspecialchars之类的函数来防止XSS攻击,或者如果您使用JSON或JavaScript编码,则使用json_encode为该上下文正确编码。

如果你在数据库中看到像这样的垃圾,可能是因为你被一些自动攻击者探测过。大多数生产站点每天都会看到成千上万的攻击企图,遗憾的是这就是现状。如果你想安静下来,你可以使用像fail2ban这样的东西禁止屡犯。


2
投票

您在表中看到了这些结果,而不是错误日志中的一系列错误抱怨格式错误的SQL表明准备好的语句+绑定变量正在执行其工作。

请注意,它不是准备好的语句来保护您免受SQL注入,而是使用绑定变量而不是从脏数据构建S​​QL语句。


1
投票

准备语句是保护您免受SQL注入的最佳方法(您应该使用广泛使用的框架,但我猜这是这种情况)

准备好的语句不会阻止您将垃圾数据导入数据库。甚至攻击向量也可能在以后被插入时成功f.e.因为html(xss)可以进入数据库。但在这种情况下,根本原因是在呈现之前缺少验证/转义而不是数据库框架。

但是,要在数据库中存档干净数据,您必须在插入数据之前验证数据(输入验证)。让我告诉你,没有简单的方法来完成所有数据,因为它取决于您在特定应用程序中的信息的性质。而且没有银弹。


1
投票

其他人是对的。您已成功避免SQL注入。

但网络蠕虫正在向你发送恶意制作的引用字符串。

您知道HTTP“referer”标头应该包含URL。远程地址字符串应包含IP地址或主机名,并附加端口号。 (不是URL)。

因此,在将referer插入数据库之前,您可以检查它以查看它是一个格式正确的URL还是恶意的。如果它是恶意的,你可以将其删除,或者将其更改为http://malicious.example.com,或者在插入之前做任何你想摆脱垃圾的事情。

在您的情况下,使用php's nice built in filtering capability。第一次设置$HTTP_REFERER后立即添加这些行。

 $HTTP_REFERER  = filter_var( $HTTP_REFERER, FILTER_VALIDATE_URL, FILTER_NULL_ON_FAILURE );
 if ( is_null( $HTTP_REFERER ) ) {
    $HTTP_REFERER = 'http://bogus-referer.example.com/';
 }

或者其他的东西。

使用FILTER_VALIDATE_IP为remote_addr执行类似操作。

记住这一点:你不是偏执狂。聪明且有动力的人实际上正在策划对你,并试图打你的网站。

© www.soinside.com 2019 - 2024. All rights reserved.