这个问题不是关于防止SQL注入攻击。 StackOverflow已经多次回答了这个问题,我已经实现了这些技术。这是关于停止 尝试 。
最近,我的网站受到大量注入攻击。现在,我捕获它们并返回一个静态页面。
以下是我的网址:
/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 answer建议使用404然后使用die(); - 机器人认为没有页面甚至可能会消失,并且没有更多资源用于显示未找到页面的消息。
header("HTTP/1.0 404 Not Found");
die();
答案 0 :(得分:6)
答案 1 :(得分:1)
您可以尝试阻止此流量通过硬件到达您的服务器。大多数进行数据包检测的设备都可以使用。我为此目的使用F5(以及其他)。 F5有一种自己的脚本语言叫做iRules,可以提供很好的控制和定制。
答案 2 :(得分: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)&gt; 10)由于大多数尝试都包含超过10个字符,因此效果非常好。
答案 3 :(得分:-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地址限制为一定数量的并发连接。许多网站管理员似乎都在鼓吹这是打击僵尸垃圾邮件的好方法,但它看起来似乎不如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请求,而不是简单地延迟或扩散它们。
祝福内容与垃圾邮件之间不断升级的战斗!