php你的验证码安全码?
作者:bea
验证码的作用主要有防止暴力破解,防止恶意灌水,防止自动提交等,在这里我就不多说了。验证码的类型也有数字、字母等,甚至厉害点的还有中文的。但是不管你的验证码多么厉害,只要你在表单验证中存在如下的失误,你的验证码就形同虚设!验证码的一般思路,就是每次登陆的地方访问一个脚本文件,该文件生成含验证码的图片并将值写入到Session里,提交的时候验证登陆的脚本就会判断提交的验证码是否与Session里的一致。 问题出现了,在登陆密码错误之后,我们不去访问生成验证图片的文件,那么如果Se
验证码的作用主要有防止暴力破解,防止恶意灌水,防止自动提交等,在这里我就不多说了。验证码的类型也有数字、字母等,甚至厉害点的还有中文的。但是不管你的验证码多么厉害,只要你在表单验证中存在如下的失误,你的验证码就形同虚设!验证码的一般思路,就是每次登陆的地方访问一个脚本文件,该文件生成含验证码的图片并将值写入到Session里,提交的时候验证登陆的脚本就会判断提交的验证码是否与Session里的一致。 问题出现了,在登陆密码错误之后,我们不去访问生成验证图片的文件,那么如果Session中的验证码没有被清空,此时验证码就是跟上次的一样,辛辛苦苦构建的验证码机制就形同虚设了。下面我们先来看一段有问题的代码:登陆部分:
CODE:
<tr> <td>管理员姓名:
td> <td><input type="text" name="username" />
td>
tr> <tr> <td>管理员密码:
td> <td><input type="password" name="password" />
td>
tr> <tr> <td>验证码:
td> <td><input type="text" name="captcha" onkeyup="pressCaptcha(this)" />
td>
tr> <tr> <td colspan="2" align="right"> <img src="index.php?act=captcha&1628020115" width="145" height="20" alt="CAPTCHA" border="1" onclick= this.src="index.php?act=captcha&"+Math.random() style="cursor: pointer;" title="看不清?点击更换另一个验证码。" />
td>
tr>?>
这里没什么问题,来看登陆验证的代码(我想这样的验证思路,也是大多数人都在用的吧):
CODE:
/*------------------------------------------------------ *///-- 验证登陆信息/*------------------------------------------------------ */if ($_REQUEST['act'] == 'signin'){ include('../includes/cls_captcha.php'); /* 检查验证码是否正确 */ $validator = new captcha(); if (!$validator->check_word($_POST['captcha'])) { sys_msg($_LANG['captcha_error'], 1); } /* 检查密码是否正确 */ $sql = "SELECT user_id, user_name, password, action_list FROM " .$ecs->table('admin_user'). " WHERE user_name='$_POST[username]' AND password='" .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'). " SET last_time='" .date('Y-m-d H:i:s', time()). "', last_ip='" .real_ip(). "'". " WHERE user_id=$_SESSION[admin_id]") OR die($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访问一下验证码的页面,就可以只提交用户名、密码、刚才得到的验证码实现暴力破解了,利用此方法,同样可以实现灌水,刷票等。大家可以看下面的图片,增强点直观的认识。 解决方法:我们需要在检查密码错误后更新验证码,对于留言等类型的,还要在提交成功后更新验证码。安全就是这样,我们总是想让自己的程序更安全,但是一般情况下,我们又总是走在常规思维里跳不出来,于是导致我们的程序出现了很多"非常规漏洞",或者叫做"缺陷",总之就是不完美。我写这篇文章除了指出上面这个问题之外,还希望大家都能行动起来,用"非常规"眼光,重新检查下自己的程序,把更多以前自己没有发现的小问题帖出来,让大家共同提高!
有用 | 无用
CODE:
<tr> <td>管理员姓名:
td> <td><input type="text" name="username" />
td>
tr> <tr> <td>管理员密码:
td> <td><input type="password" name="password" />
td>
tr> <tr> <td>验证码:
td> <td><input type="text" name="captcha" onkeyup="pressCaptcha(this)" />
td>
tr> <tr> <td colspan="2" align="right"> <img src="index.php?act=captcha&1628020115" width="145" height="20" alt="CAPTCHA" border="1" onclick= this.src="index.php?act=captcha&"+Math.random() style="cursor: pointer;" title="看不清?点击更换另一个验证码。" />
td>
tr>?>
这里没什么问题,来看登陆验证的代码(我想这样的验证思路,也是大多数人都在用的吧):
CODE:
/*------------------------------------------------------ *///-- 验证登陆信息/*------------------------------------------------------ */if ($_REQUEST['act'] == 'signin'){ include('../includes/cls_captcha.php'); /* 检查验证码是否正确 */ $validator = new captcha(); if (!$validator->check_word($_POST['captcha'])) { sys_msg($_LANG['captcha_error'], 1); } /* 检查密码是否正确 */ $sql = "SELECT user_id, user_name, password, action_list FROM " .$ecs->table('admin_user'). " WHERE user_name='$_POST[username]' AND password='" .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'). " SET last_time='" .date('Y-m-d H:i:s', time()). "', last_ip='" .real_ip(). "'". " WHERE user_id=$_SESSION[admin_id]") OR die($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访问一下验证码的页面,就可以只提交用户名、密码、刚才得到的验证码实现暴力破解了,利用此方法,同样可以实现灌水,刷票等。大家可以看下面的图片,增强点直观的认识。 解决方法:我们需要在检查密码错误后更新验证码,对于留言等类型的,还要在提交成功后更新验证码。安全就是这样,我们总是想让自己的程序更安全,但是一般情况下,我们又总是走在常规思维里跳不出来,于是导致我们的程序出现了很多"非常规漏洞",或者叫做"缺陷",总之就是不完美。我写这篇文章除了指出上面这个问题之外,还希望大家都能行动起来,用"非常规"眼光,重新检查下自己的程序,把更多以前自己没有发现的小问题帖出来,让大家共同提高!
有用 | 无用
猜你喜欢
您可能感兴趣的文章:
- SMARTY学习手记
- 笑谈配置,使用Smarty技术
- Smarty模板快速入门
- 菜鸟学PHP之Smarty入门
- 推荐php模板技术[转]
- 推荐个功能齐全的发送PHP邮件类
- php和js交互一例-PHP教程,PHP应用
- URL Rewrite的设置方法
- 帖几个PHP的无限分类实现想法~
- PHP+MYSQL开发工具及资源收藏
- 分享PHP入门的学习方法
- php中常用编辑器推荐
- PHP中的日期处理方法集锦
- PHP语法速查表
- 影响PHP+MYSQL执行速度的写法对比
- require(),include(),require_once()和include_once()的异同
- 开发大型 PHP 项目的方法
- phpwind中的数据库操作类
- PHP无限分类的类