我们常常在提交页面设置验证码防止重复提交,但有些时候设置了验证码不一定有用,看看下面的例子: 实现用户注册的功能,需要提交以下字段:username,password,regCode,注册成功后跳转到登录页面,接受页面进行如下处理: if($_POST['regCode'] != $_SESSIO
我们常常在提交页面设置验证码防止重复提交,但有些时候设置了验证码不一定有用,看看下面的例子:
实现用户注册的功能,需要提交以下字段:username,password,regCode,注册成功后跳转到登录页面,接受页面进行如下处理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | if ( $_POST [ 'regCode' ] != $_SESSION [ 'regCode' ]) {
msg( '验证码不一致' );
}
$username = $_POST [ 'username' ];
$password = $_POST [ 'password' ];
if (! check_username( $username )) {
msg( '用户名不合法' );
}
if (! check_password( $password ))) {
msg( '密码不合法' );
}
if (check_user_exists( $username )) {
msg( '用户名已被占用' );
}
if (! $this ->user_model->save( array (
'username' => $username ,
'password' => $password ,
))) {
msg( '注册失败' );
}
header( "Location:login.php" );
|
Nach dem Login kopieren
可以看到对用户名、密码都做了校验,且设置了验证码,那是不是就没问题了呢?可以看到服务端只做了验证码校验,但在使用完验证码后并未删掉验证码,这样在下次请求中验证码是否可以重复使用呢?
我们知道验证码通常情况下存储在SESSION中,只要SESSION中验证码不被删掉而客户端请求的CookieID相同,服务端会认为是同一个用户,根据同一个CookieID想必服务端还可以拿到验证码再次使用。
我们可以这个动作用程序来模拟,并尝试多次执行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | $cookie = 'PHPSESSID=pgfac511q271k5vvije46kf634' ;
$post_data = array (
'username' => 'pp' .time(),
'password' => time(),
'regCode' => 'dksi' ,
);
$ch = curl_init( "http://localhost/regist.php" );
curl_setopt( $ch , CURLOPT_HEADER, true);
curl_setopt( $ch , CURLOPT_RETURNTRANSFER, true);
curl_setopt( $ch , CURLOPT_POST, true);
curl_setopt( $ch , CURLOPT_POSTFIELDS, http_build_query( $post_data ));
curl_setopt( $ch ,CURLOPT_HTTPHEADER, array ( "Cookie: " . $cookie ));
$rs = curl_exec( $ch );
if (curl_errno( $ch )) {
throw new Exception( 'Curl Error:' .curl_error( $ch ));
}
curl_close( $ch );
var_dump( $rs );
|
Nach dem Login kopieren
我们只需要从浏览器上取到产生的cookie内容和显示的验证码即可,而这些通过ff或者chrome很容易就可以拿到。多次执行之后会发现数据库插入了多条记录,也就是验证码没有起到防刷的目的。同样,也可以在提交页面的时候尝试直接F5刷新,上面的逻辑则会提示用户名已被占用。
该问题产生的根本原因就是验证码使用一次之后还可以再次使用,所以解决也很简单,只需要在注册成功之后清掉验证码的值即可,再次请求时服务端session里已经没有该值了,验证码就校验不通过了。
这样的问题本属于很小的问题,但是在系统中不经意就发生了,不要让验证码变得毫无意义,等刷了几百万用户后才后知后觉^_^
原文地址:没用的验证码, 感谢原作者分享。