验证码的一般思路,就是每次登陆的地方访问一个脚本文件,该文件生成含验证码的图片并将值写入到Session里,提交的时候验证登陆的脚本就会判断提交的验证码是否与Session里的一致。
问题出现了,在登陆密码错误之后,我们不去访问生成验证图片的文件,那么如果Session中的验证码没有被清空,此时验证码就是跟上次的一样,辛辛苦苦构建的验证码机制就形同虚设了。
下面我们先来看一段有问题的代码:
登陆部分:
CODE:
< />tr>
< />tr>
< />tr>
< />td>
< />tr>
?>这里没什么问题,来看登陆验证的代码(我想这样的验证思路,也是大多数人都在用的吧):
CODE:
/*------------------------------------------------------*/
//--验证登陆信息
/*------------------------------------------------------*/
if($_REQUEST['act']=='signin')
{
include('../includes/cls_captcha.php');
/*检查验证码是否正确*/
$validator=newcaptcha();
if(!$validator->check_word($_POST['captcha']))
{
sys_msg($_LANG['captcha_error'],1);
}
/*检查密码是否正确*/
$sql="SELECTuser_id,user_name,password,action_listFROM".$ecs->table('admin_user').
"WHEREuser_name='$_POST[username]'ANDpassword='".md5($_POST['password'])."'";
$row=$db->GetRow($sql);
if($row)
{
//登录成功
set_admin_session($row['user_id'],$row['user_name'],$row['action_list']);
//更新最后登录时间和IP
$db->Execute("UPDATE".$ecs->table('admin_user').
"SETlast_time='".date('Y-m-dH:i:s',time())."',last_ip='".real_ip()."'".
"WHEREuser_id=$_SESSION[admin_id]")ORdie($db->ErrorMsg());
if(isset($_POST['remember']))
{
setcookie('ECSCP[admin_id]',$row[0],time()+3600*24*360);
setcookie('ECSCP[admin_pass]',md5($row['password'].$_CFG['hash_code']),time()+3600*24*360);
}
header('location:./');
}
else
{
sys_msg($_LANG['login_faild'],1);
}
}
?>问题就出在上面这段代码里,在检查密码错误之后,并没有更新验证码,这样我们就可以把登陆页面的验证码图片部分去掉,而只要用URL访问一下验证码的页面,就可以只提交用户名、密码、刚才得到的验证码实现暴力破解了,利用此方法,同样可以实现灌水,刷票等。
大家可以看下面的图片,增强点直观的认识。
解决方法:我们需要在检查密码错误后更新验证码,对于留言等类型的,还要在提交成功后更新验证码。
安全就是这样,我们总是想让自己的程序更安全,但是一般情况下,我们又总是走在常规思维里跳不出来,于是导致我们的程序出现了很多"非常规漏洞",或者叫做"缺陷",总之就是不完美。我写这篇文章除了指出上面这个问题之外,还希望大家都能行动起来,用"非常规"眼光,重新检查下自己的程序,把更多以前自己没有发现的小问题帖出来,让大家共同提高!
相关推荐
- php判断当前页面是不是在微信里面打开
- PHP 采集心得技巧
- DISCUZ 论坛管理员密码忘记的解决方法
- PHP获取当前文件所在目录 getcwd()函数
- 示例详解Laravel的注册重构
- PHP实现路由映射到指定控制器
- 谈谈PHP连接Access数据库的注意事项
- 总结PHP中DateTime的常用方法
- php使用curl详细解析及问题汇总
- 示例详解Laravel重置密码代码重构
- 修改Laravel5.3中的路由文件与路径
- 教你在header中隐藏php的版本信息
- PHP怎样用正则抓取页面中的网址
- php阳历转农历优化版
- 常用PHP数组排序函数归纳
- PHP+JQuery+Ajax实现分页方法详解
- 微信自定义菜单的创建/查询/取消php示例代码
- Thinkphp微信公众号支付接口
- 浅析Laravel5中队列的配置及使用
- php微信支付接口开发程序