这个方案应该是目前所接触到的比较完善的一个防注入方案,远不是网上流传的防SQL注入代码所能相比的。
MysqlIds是由在国内安全界很著名的web安全研究组织80SEC在2008年编写。
使用MysqlIds可以更好的、更有效率的帮助网站管理员和程序员抵御和检测Sql注射漏洞。dedecms自08年底以来的版本中已经整合进了这个程序。
MysqlIds原理
MysqlIds由PHP编写,通过一个封装的安全函数,监测程序中运行的SQL查询语句,针对黑客经常使用的union查询、select子查询、不常用的SQL注释符、文件操作和benchmark等危险函数行为进行报警。
这个IDS是无缝封装在程序里的数据库操作流程里的,也就是黑客通过程序漏洞进行恶意的SQL注射都能被非常详细的监测到。
程序员或者网站站长甚至能使用IDS发现自己网站程序中未被察觉的0DAY漏洞。
Mysqlids的检测工作使用php实现,相对于SQL语句来说消耗的时间非常小,合理地部署Mysqlids可以极大地提高程序的安全性。
MysqlIds日志
当程序的SQL语句被监测到恶意行为后,会打开相应条件语句里的fail开关,也就是触发监测后根据信息会留下一条精确的日志信息。管理员排查日志就能精确定位程序中的SQL注射漏洞。
MysqlIds安装
MysqlIds暂时只支持PHP+MYSQL架构的Web程序,作为开源程序和其原理的灵活性,大家可以很方便将MysqlIds和自己程序无缝结合。
我们可以参考DeDecms的MYSQL数据库类,将MysqlIds部署在程序中:\include\dedesql.class.php
DeDecms的MYSQL数据库类的ExecuteNoneQuery函数封装了MysqlIds,程序运行的SQL语句在进入MYSQL查询之前都会使用MysqlIds的CheckSql函数处理。
if($this->safeCheck) CheckSql($this->queryString,’update’);return mysql_query($this->queryString,$this->linkID);
然后以此案例自己选择合适的添加位置即可。
MysqlIds下载
将下列代码复制下来即可。
<?php
/*MYSQL Injection IDS [ver.1.0]
BY 80sec http://www.80sec.com/
函数严格限制SQL文里出现
###########################################
union查询
select子查询
不常用的注释
文件操作
benchmark等危险函数
###########################################本函数适合一些开放代码的程序(因为这些程序需要考虑到在各种版本的Mysql里运行),但是可能并不适合在你的程序里,你可以通过修改自己的程序或者做合适的配置来适应它另外对于正常的SQL语句,由于本程序使用的是操作相对来说比较快的strpos来实现的,所以效率影响不是很大:)
关于使用:
1 本函数是在MYSQL操作层来检测非法的SQL查询,大部分情况下该查询是由入侵者引起的,您可能也需要调整自己的程序,本程序不能作为过滤函数
2 本函数需要部署在mysql_query函数前面,作为检测即将执行的SQL语句,最好将他部署在你的MYSQL操作类的前面
3 非法操作默认记录在根目录下,名字为站点根目录的md5值任何建议欢迎与
root#80sec.com
联系:)
*/
function check_sql($db_string){
$clean = ”;
$error=”;
$old_pos = 0;
$pos = -1;
$log_file=$_SERVER['DOCUMENT_ROOT'].md5($_SERVER['DOCUMENT_ROOT']).”.php”;while (true)
{
$pos = strpos($db_string, ‘\”, $pos + 1);
if ($pos === false)
break;
$clean .= substr($db_string, $old_pos, $pos – $old_pos);while (true)
{
$pos1 = strpos($db_string, ‘\”, $pos + 1);
$pos2 = strpos($db_string, ‘\\’, $pos + 1);
if ($pos1 === false)
break;
elseif ($pos2 == false || $pos2 > $pos1)
{
$pos = $pos1;
break;
}$pos = $pos2 + 1;
}
$clean .= ‘$s$’;$old_pos = $pos + 1;
}$clean .= substr($db_string, $old_pos);
$clean = trim(strtolower(preg_replace(array(‘~\s+~s’ ), array(‘ ‘), $clean)));
//老版本的Mysql并不支持union,常用的程序里也不使用union,但是一些黑客使用它,所以检查它
if (strpos($clean, ‘union’) !== false && preg_match(‘~(^|[^a-z])union($|[^[a-z])~s’, $clean) != 0){
$fail = true;
$error=”union detect”;
}
//发布版本的程序可能比较少包括–,#这样的注释,但是黑客经常使用它们
elseif (strpos($clean, ‘/*’) > 2 || strpos($clean, ‘–’) !== false || strpos($clean, ‘#’) !== false){
$fail = true;
$error=”comment detect”;
}
//这些函数不会被使用,但是黑客会用它来操作文件,down掉数据库
elseif (strpos($clean, ‘sleep’) !== false && preg_match(‘~(^|[^a-z])sleep($|[^[a-z])~s’, $clean) != 0){
$fail = true;
$error=”slown down detect”;
}
elseif (strpos($clean, ‘benchmark’) !== false && preg_match(‘~(^|[^a-z])benchmark($|[^[a-z])~s’, $clean) != 0){
$fail = true;
$error=”slown down detect”;
}
elseif (strpos($clean, ‘load_file’) !== false && preg_match(‘~(^|[^a-z])load_file($|[^[a-z])~s’, $clean) != 0){
$fail = true;
$error=”file fun detect”;
}
elseif (strpos($clean, ‘into outfile’) !== false && preg_match(‘~(^|[^a-z])into\s+outfile($|[^[a-z])~s’, $clean) != 0){
$fail = true;
$error=”file fun detect”;
}
//老版本的MYSQL不支持子查询,我们的程序里可能也用得少,但是黑客可以使用它来查询数据库敏感信息
elseif (preg_match(‘~\([^)]*?select~s’, $clean) != 0){
$fail = true;
$error=”sub select detect”;
}if (!empty($fail))
{fputs(fopen($log_file,’a+’),”<?php die();?>||$db_string||$error\r\n”);
die(“Hacking Detect<br><a href=http://www.80sec.com/>http://www.80sec.com</a>”);
}else {
return $db_string;
}
}/*
$sql=”select * from news where id=’”.$_GET[id].”‘”; //程序功能的SQL语句,有用户数据进入,可能存在SQL注射check_sql($sql); //用我们的函数检查SQL语句
mysql_query($sql); //安全的数据库执行
*/
2 回应 至“”PHP防注入方案——WEB版ID””

呵呵,学习了~
呵呵 学习了