Php 每天18000次MySQL注入尝试:停止尝试

Php 每天18000次MySQL注入尝试:停止尝试,php,mysql,security,Php,Mysql,Security,这个问题与防范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%

这个问题与防范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
这就是攻击的样子:

/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()
而消失。这种方法有什么问题吗?或者是否有一个HTML返回代码,我可以用PHP设置,这将更合适

编辑:

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

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

过滤掉可能的注射尝试才是目的

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


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

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

我提出了一个非常好的问题+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_油门”。使用该方法,您可以通过将以下指令添加到Apache配置文件中,将每个IP地址限制为每5秒一次访问:

<IfModule mod_throttle.c>
    ThrottlePolicy Request 1 5
</IfModule>
另一个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请求,而不是简单地延迟或分散它们


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

帖子已被解锁,所以我想我应该分享一下我为减少来自同一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();
    }
}

只需使用prepared statement返回403错误可能有点合适。服务器前面有F5负载平衡器吗?@bksi如果您阅读第一行,您会注意到这不是问题的重点。这个问题与编程无关,是服务器管理。谢谢。我会调查的。IP地址经常变化,所以这是不可行的。这是可行的。找出这些请求的一个特征,这是普通用户极不可能或不可能触发的,然后在他们触发时立即禁止IPs。我得到了匿名否决票。Downvoter,你能留下评论告诉我为什么你认为这个答案不好吗?也许我可以改进它。我正在使用一个虚拟的私有服务器,所以我不认为这是一个选项,但我会研究它们提供了什么。