6

这个问题与防止 SQL 注入攻击无关。这个问题在 StackOverflow 上已经回答了很多次,我已经实现了这些技术。这是关于停止尝试

最近,我的网站遭到了大量注入攻击。现在,我捕获它们并返回一个静态页面。

这是我的 URL 的样子:

/products/product.php?id=1

这是攻击的样子:

/products/product.php?id=-3000%27%20IN%20BOOLEAN%20MODE%29%20UNION%20ALL%20SELECT%2035%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C%27qopjq%27%7C%7C%27ijiJvkyBhO%27%7C%7C%27qhwnq%27%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35%2C35--%20

我确信这不仅仅是一个错误的链接或粗手指打字,所以我不想将它们发送到概述页面。我也不想在我的网站上使用任何资源来提供静态页面。

我正在考虑让页面与die(). 这种方法有什么问题吗?或者是否有一个我可以用 PHP 设置的更合适的 HTML 返回代码?

编辑:

根据下面的几条评论,我查找了如何返回“找不到页面”。icktoofay 的这个 Stack Overflow回答建议使用 404,然后使用 die(); - 机器人认为没有页面甚至可能消失,并且没有更多资源用于显示页面未找到消息。

header("HTTP/1.0 404 Not Found");
die();
4

4 回答 4

6

过滤掉可能的注入尝试是mod_security的用途。

配置它以识别对您的应用程序的合法请求可能需要相当多的工作。

另一种常见的方法是在检测到恶意客户端的 IP 地址时阻止它们。

于 2013-08-15T18:01:19.937 回答
1

您可以尝试通过硬件阻止此流量到达您的服务器。大多数进行数据包检查的设备都可以使用。我为此使用 F5(等等)。F5 有自己的脚本语言,称为 iRules,可提供出色的控制和自定义功能。

于 2013-08-15T18:10:40.667 回答
0

该帖子已被解锁,所以我想我会分享我一直在做的事情,以减少来自同一 IP 地址的攻击。我仍然每天得到半打,但他们通常只从每个 IP 地址尝试一次或两次。

注意:为了返回 404 错误消息,所有这些都必须在发送任何 HTML 之前出现。我正在使用 PHP 并将所有错误重定向到错误文件。

<?php
require_once('mysql_database.inc');

// I’m using a database, so mysql_real_escape_string works.
// I don’t use any special characters in my productID, but injection attacks do. This helps trap them.
$productID = htmlspecialchars( (isset($_GET['id']) ? mysql_real_escape_string($_GET['id']) : '55') );

// Product IDs are all numeric, so it’s an invalid request if it isn’t a number.
if ( !is_numeric($productID) ) {
    $url = $_SERVER['REQUEST_URI'];  // Track which page is under attack.
    $ref = $_SERVER['HTTP_REFERER']; // I display the referrer just in case I have a bad link on one of my pages
    $ip  = $_SERVER['REMOTE_ADDR'];  // See if they are comng from the same place each time

    // Strip spaces just in case they typed the URL and have an extra space in it
    $productID=preg_replace('/[\s]+/','',$productID);
    if ( !is_numeric($productID) ) {
        error_log("Still a long string in products.php after replacement: URL is $url and IP is $ip & ref is $ref");
        header("HTTP/1.0 404 Not Found");
        die();
    }
}

我还有很多页面,根据选择的类别,我会在其中显示不同的内容。在这些情况下,我有一系列 if 语句,像这样if ($cat == 'Speech') { }没有数据库查找,所以没有 SQL 注入的机会,但我仍然想停止攻击而不浪费带宽向机器人显示默认页面。通常类别是一个简短的单词,所以我修改了上面的is_numeric条件来检查字符串长度,例如if ( strlen($cat) > 10 )因为大多数尝试中包含超过 10 个字符,所以效果很好。

于 2014-08-21T19:45:39.733 回答
-1

我提出了一个非常好的问题+1,答案并不简单。

PHP 不提供维护不同页面和不同会话的数据的方法,因此您不能通过 IP 地址限制访问,除非您将访问详细信息存储在某处。

如果您不想为此使用数据库连接,您当然可以使用文件系统。我确定您已经知道如何执行此操作,但您可以在此处查看示例:

DL's Script Archives
http://www.digi-dl.com/
(click on "HomeGrown PHP Scripts", then on "IP/networking", then
on "View Source" for the "IP Blocker with Time Limit" section)

最好的选择曾经是“mod_throttle”。使用它,您可以通过将此指令添加到您的 Apache 配置文件来将每个 IP 地址限制为每五秒一次访问:

<IfModule mod_throttle.c>
    ThrottlePolicy Request 1 5
</IfModule>

但也有一些坏消息。mod_throttle 的作者已经放弃了该产品:

"Snert's Apache modules currently CLOSED to the public 
  until further notice. Questions as to why or requests
  for archives are ignored."

另一个 apache 模块 mod_limitipconn 现在更常用。它不允许您做出任意限制(例如“每十五秒内不超过十个请求”)。您所能做的就是将每个 IP 地址限制为一定数量的并发连接。许多网站管理员似乎都在提倡将其作为对抗 bot 垃圾邮件的好方法,但它似乎不如 mod_throttle 灵活。

您需要不同版本的 mod_limitipconn,具体取决于您运行的 Apache 版本:

mod_limitipconn.c - for Apache 1.3
http://dominia.org/djao/limitipconn.html

mod_limitipconn.c - Apache 2.0 port
http://dominia.org/djao/limitipconn2.html

最后,如果您的 Apache 服务器托管在 Linux 机器上,那么您可以使用一个不涉及重新编译内核的解决方案。相反,它使用“iptables”防火墙规则。这种方法相当优雅,并且足够灵活,可以施加诸如“一分钟内来自该 IP 的连接不超过三个”之类的限制。这是如何完成的:

Linux Noob forums - SSH Rate Limit per IP
http://www.linux-noob.com/forums/index.php?showtopic=1829

我意识到这些选项都不是理想的,但它们说明了什么是可能的。也许使用本地数据库最终会是最好的?无论如何,请记住,简单地限制请求速率或限制带宽并不能解决机器人问题。它们可能需要更长的时间,但它们最终会消耗与不放慢速度时一样多的资源。有必要实际拒绝他们的 HTTP 请求,而不是简单地延迟或分散它们。

在内容和垃圾邮件之间不断升级的战斗中祝你好运!

于 2013-08-15T18:25:20.510 回答