用一些SQL注入工具来检测自己的后台...发现显示能注入..想求教一下怎么防注入在表单的检测里已经过滤掉了所有非法的字符.....现在不知道怎么从URL里过滤掉非法字符...想弄清楚URL注入原理和防注入的方法......工具里的这些有些不太懂XXXX.com/adminlogin.php/**/and/**/1=1
XXXX.com/adminlogin.php/**/and/**/1=1/**/union/**/select/**/1,2,3,4,5,6,7,8,9/*到底是怎么从地址里面提交查询的?
XXXX.com/adminlogin.php/**/and/**/1=1/**/union/**/select/**/1,2,3,4,5,6,7,8,9/*到底是怎么从地址里面提交查询的?
1、php 为防范 SQL注入 已经采取了措施:一次只能执行一条 SQL 指令。这就断绝了通过重构sql指令来造成灾难性所害的途径。(附加 delete、drop)
2、一个例外是 mysqli_multi_query,他允许一次执行多条指令。由此带来的风险,要由使用者自己来承担的
3、仅仅改变查询条件(恒成立)并不构成威胁,至多是入侵者具备了网站管理员的权限,这个可以通过首先插入一个特殊名称的管理员来解决。只要检查到用户名为该名称时就退出程序
4、或是看到了本不该出现在本栏目的数据,但这并不影响其他用户的正常浏览总之,大可不必谈虎色变的
XXXX.com/adminlogin.php/**/and/**/1=1/**/union/**/select/**/1,2,3,4,5,6,7,8,9/*
我看到过的一个注入猜解例子就是这样的.....能说明一下吗?谢谢
2、mysql_query()同样有风险。
3、不仅仅网站管理员的权限,整个网站与数据库数据都会被拿下都有可能,如果网站运行环境比较脆弱,服务器权限被拿下都有可能。
总之过滤是还是很必要的。
@session_start();
include("conn.php");
$user=$_POST['user'];
$pwd=$_POST['pwd'];
if(@preg_match("/select|delete|or|and|declare|exec|turncate|\*|=|'/i",$pwd)||@preg_match("/select|delete|or|and|declare|exec|turncate|\*|=|'/i",$user))
{
echo "<script>alert('非法字符!!!');</script>";
$a=$_SERVER["HTTP_REFERER"];
echo "<meta http-equiv=refresh content='0; url=$a'>";
}
else
{
$result =mysql_query("select adminuser,adminpwd,power from admin where adminuser='$user'");
if(mysql_num_rows($result)==1)
{ $result2=mysql_fetch_array($result);
$sec=md5($pwd);
if($result2['adminpwd']==$sec)
{
@$_SESSION['pass']=$user;
$power=$result2['power'];
echo "<script>alert('成功登陆.权限等级:".$power."');</script>";
echo "<meta http-equiv=refresh content='0; url=adminaccess.php'>";
}
else
{
echo "密码错误!";
$a=$_SERVER["HTTP_REFERER"];
echo "<meta http-equiv=refresh content='2; url=$a'>";
}
}
else
{
echo "无该用户!!!";
$a=$_SERVER["HTTP_REFERER"];
echo "<meta http-equiv=refresh content='2; url=$a'>";
}
}
?>
以楼主 #14 的代码为例
$result =mysql_query("select adminuser,adminpwd,power from admin where adminuser='$user'");
if(mysql_num_rows($result)==1)
如果sql指令被你篡改成了 select adminuser,adminpwd,power from admin
那么你就没法通过 if(mysql_num_rows($result)==1) 的检验
因为既然有用户那么就不会是有一个如果sql指令被你篡改成了 select adminuser,adminpwd,power from admin limit 1
那你依然不能通过其后的 if($result2['adminpwd']==$sec) 的检验如果楼主是将用户名和口令放在sql指令中一并匹配,那么你有可能获得第一个或最后一个用户的权限字。但如我#7的描述,你可能正好掉入我设陷阱里因此
if(@preg_match("/select|delete|or|and|declare|exec|turncate|\*|=|'/i",$pwd)||@preg_match("/select|delete|or|and|declare|exec|turncate|\*|=|'/i",$user))
{
echo "<script>alert('非法字符!!!');</script>";
$a=$_SERVER["HTTP_REFERER"];
echo "<meta http-equiv=refresh content='0; url=$a'>";
}
是无意义的,当然也是不完整的
这个地方比你想象的宽松多了,是可以执行你书写的代码的如果你把它弄瘫痪了,新浪一定会有重金奖赏的
$_SESSION['pass']=$user;
什么原因呢?再改回一次加密...就又正常了
session_start(); 了吗?另外,你为何用 @ 屏蔽错误?
Warning: session_start() [function.session-start]: Cannot send session cookie - headers already sent by (output started at /adminaccess.php:1) in www/adminaccess.php on line 2Warning: session_start() [function.session-start]: Cannot send session cache limiter - headers already sent (output started at /www/adminaccess.php:1) in /adminaccess.php on line 2
//#14部分代码略去......
$sec=MD5(md5($pwd));
if($result2['adminpwd']==$sec)
{
@$_SESSION['pass']=$user;
//#14部分代码略去......
跳转到
adminaccess.php<?php
@session_start();
ob_start('Content-type: text/html;charset=utf-8');
$pass=$_SESSION['pass'];if(isset($pass))
{
//此处代码略去}
else
{ echo "未登录用户禁止访问管理员模块!";
include("adminlogin.php");
}
?>
那么 session_start(); 就无效了既然 session_start(); 无效了,那 session 变量还能正常吗?
@屏蔽了错误不算输出吧??
而且之前也试过去掉@...一样无法显示正常....
不屏蔽错误的话
Warning: session_start() ....你不把错误改掉,就不能正确运行
仅仅回避掉是不行的!只能后患无穷
转成无bom的即可