TokenCode,防止机器人模拟提交方式注册

最近一个朋友网站,使用短信注册验证+验证码。短信验证竟然也能被识别(搜索发现,现在有接收平台)。程序使用的国内最知名的那个商城系统。树大招风,估计有人专门谢了注册工具。
通过分析,发现注册工具直接调用的注册提交页面。每个会员注册网站访问日志记录只有三条,发送手机验证码、验证码、注册提交页面。
因为使用了默认了验证码,很容易识别,最简单的方式就是更换复杂的验证码脚本即可防止恶意注册。但是这样还有个非常严重的问题,如果同行恶意操作。随便填写手机号,发出几万个请求,几分钟就能完成。几千短信费用估计就进去了。交流再三,还是决定在短信验证码上做文章。

既然他是通过模拟提交的,给短信发送页面增加token即可解决。当然后期他可能会发现,抓去注册页面的token,附加到短信请求验证码页面即可。但是我们可以把token做的非常复杂,借助浏览器的js计算。即使他抓去了计算式也没用,用其他语言解析执行JS代码很难(或许有,我不知道,但是能增加他的难度)。如下图:

tokencode

流程确定了,剩下的就简单了。写成了,方便调用,源程序上做很少修改即可使用。直接上代码:

<?php
	#=====================================================================
	#=                 Copyright (c) 2015 猫七(QQ:77068320)              =
	#=                      All rights reserverd.                        =
	#=====================================================================
	#=           TokenCode 防模拟提交程序 类(PHP版本)                    =
	#=  使用说明:http://www.miaoqiyuan.cn/products/tokencode/last.zip   =
	#=  演示地址:http://www.miaoqiyuan.cn/products/tokencode/           =
	#=  使用说明:http://www.miaoqiyuan.cn/p/tokencode                   =
	#=  邮箱地址:mqycn@126.com   QQ:77068320 1301425789                =
	#=====================================================================
	
	class TokenCode {
		public $value, $code ;
		public $OperationList;
		public function __construct() {
			$resultValue = $this -> RandomKey($this -> RandomIntger());
			$resultCode = "'" . $resultValue . "'";
			$this -> OperationList = Array("+", "-" ,"*");
			
			for( $i = 0 ; $i < $this -> RandomIntger() + 3; $i++){
				$op =  $this -> RandOperation();
				switch($op){
					case "+":
					case "-":
						$random = $this -> RandEquations();
						$resultValue .= $random["value"];
						$resultCode .= "+(" . $random["code"] . ")";
						break;
					default:
						$random = $this -> RandomKey($this -> RandomIntger());
						$resultValue .= $random;
						$resultCode .= "+'" . $random . "'";
						break;
				}
			}
			
			$rnd1 = $this -> RandomIntger();
			$rnd2 = $this -> RandomIntger() + 8;
			$this -> value = substr($resultValue, $rnd1, $rnd2);
			$this -> code = "(" . $resultCode . ").substring(" . $rnd1 . "," . ($rnd1 + $rnd2) . ")";
		}
		
		private function RandEquations(){
			$va = $str = $this -> RandomLong();
			$this -> OperationList = Array("+", "-" ,"*");
			
			for( $i = 0 ; $i < $this -> RandomIntger(); $i++){
				$op =  $this -> RandOperation();
				$vb = $this -> RandomLong();
				switch($op){
					case "+":
						$va += $vb;
						$str .= "+" . $vb;
						break;
					case "-":
						$va -= $vb;
						$str .= "-" . $vb;
						break;
					case "*":
						$va *= $vb;
						$str = "(" . $str . ")*" . $vb;
						break;
				}
			}
			return Array(
				"code" => $str,
				"value" => $va
			);
		}
		
		private function RandOperation(){
			return $this -> OperationList[rand() % count($this -> OperationList)];
		}
		
		private function RandomIntger(){
			return (int)substr(rand(), 1, 1) + 1;
		}
		
		private function RandomLong(){
			return (int)substr(rand(), 1, 3) + 1;
		}
		
		private function RandomKey($len = 10){
			return substr(md5(rand()), 1, $len + 5);
		}
		
	}
?>

调用方法:

<?php
	require("TokenCode.php");
	$token = new TokenCode();
	$tokenValue = $token -> value ;
	$tokenCode = $token -> code ;
        
	//代码段
        $_SESSION["_TOKENCODE"] = $token -> value ;
        
	//代码段
	echo '<script type="text/javascript">_TOKENCODE=' . $token -> code . ';</script>';
?>

保存好session后,到验证页验证提交的code和验证结果即可,程序改动非常少,只需要js改动一下即可。

#AJAX方式
$.post("/", {mob : $("#mob").val() , token : _TOKENCODE }, function(){ } );

#URL方式
$("#send").click(function(){
	if(this.href.indexOf('&token=')==-1){
		this.href+='&token=' + _TOKENCODE
	};
});

测试地址:http://www.miaoqiyuan.cn/products/tokencode/
下载地址:http://www.miaoqiyuan.cn/products/tokencode/last.zip

TokenCode,防止机器人模拟提交方式注册》上有3条评论

  1. mqycn 文章作者

    现在NodeJS也是我掌握的语言之一了。即使使用NodeJS,正则得到我的token的JS代码。处于安全考虑,应该也不敢去eval执行吧。不然分分钟会被黑的。

发表评论

电子邮件地址不会被公开。 必填项已用*标注