首页 > 关于一个投票系统的问题,如何防止刷票

关于一个投票系统的问题,如何防止刷票

像验证手机号的代价太大,咱就不说了;像验证码这样的,如何设置最好;还有没有其他更加有效的方式?


现在刷票牛逼的都用人来搞了。我曾经做过投票系统,记录了投票者的IP,然后我发现有很多处于同一网段的地址,后来我查了下这些IP的归属地,发现都是外地的,最后我就把这种连续IP地址的投票保留一票,其他的都删掉。


我觉得这不是个技术问题,应该是个产品管理的问题。纯技术手段必须要结合你对这个“投票”的产品的经营策略才能发挥最大效用。就像刚才有人说的,如果你只是把这个产品定义成一个只能完成简单survey功能的(只有几个记录选项然后upload再汇总的功能)简单产品,那你就要添加许许多多的技术手段来保证你这个产品实现你的预期功能(确实反映客观投票结果)。但是如果你提前在设计产品的时候,以结果为导向,把这一块考虑进去,那么你就应该考虑到对用户的过滤是此产品很关键的一环,而不至于等到先把投票功能开发完了,再回过头去考虑“防刷票”,这是本末倒置,说明产品设计流程有问题。

如果你能解决上面我说的问题,就应该一开始就想到,要先过滤用户,再让过滤出来的用户“干什么”(不管是投票还是评论还是别的什么)。所以应该先搞一个准入制度,比如注册,验证,答题激活,推荐激活,间隔日期激活,积分功能激活权限等等手段来尽量拔高门槛,然后再考虑利用这批过滤出来的用户来做什么。这样才是解决这个问题的正确思考顺序。


我就直说吧:放弃你的幻想。没有任何方式是必然有效的。

一切防刷的努力都能被破解,只要肯花钱。以我接触过的一些价格举例:

(注意:黑产的价格都是模糊、飘忽且各地极其分散的,难有默契或者“行情”。根据个人接触的圈子不同,具体价格不尽准确。)

不要低估互联网黑产这门行业——它远远超出我们一般技术人的想象。

防刷不能靠一门单一的技术,而是要综合分析可能的破解手段,评估攻击者愿意做到什么地步,以和黑产打一场全面战争的角度思考问题。即:如何以最小的消耗,来最大限度的浪费黑产的时间和金钱

而这种问题必然是没有银弹的。所有只提出一种单一手段的答案都该被踩——“技术解决一切”对于某些场合,是一种过于幼稚的幻想,得让现实需求好好削几个耳光治一治。


从这个意义上,单纯的提问这个问题,信息量太少了。具体策略必然需要根据具体的场景而定。例如:

一般而言,以下的几种方法是比较划算的(即破解这些需要相对多的时间和金钱):


这个确实不容易,假投票主要来自于:

  1. 机器人:这个基本还是需要靠验证码。机器难以识别的验证码人也不容易识别,但似乎也没有更好的办法。
    2.水军:这个需要分析用户行为,把水军账号找出来


这个真没办法,做过第一名只有300块的奖金,结果刷票就有几千票了,按一个0.5计算,刷票成本都高过奖金价值了


如果没有帐号体系, 那么防止刷票要通过ip来判断,
获取ip得用$_server[remote_addr]来获取用户ip。


我来说说验证码。
如果你要设置验证码,请遵循以下几点。 一般这种验证码出现,我就搞不定了。

  1. 字符之间随机互相连接. 加大切分难点。

  2. 字符随机扭曲. 配合连接把切分难度增加一个指数。

  3. 随机旋转. 本身没有增加识别难度,不过配合上面2项增加了切分难度

  4. 单一颜色. 不要搞多种颜色, 单一颜色反而更难切分。

  5. 随机中文。 相比于英文,如果配合以上几项,基本上切分已经变成一件很困难的事情,如果真的要破成本会很高。

PS: 还有其他一些可以增加难度的事情, 不过以上本身已经会让人眼识别成功率不超过50%了, 再加已经没有太大意义。PS 第5项目 换成英文会提高人眼识别和机器识别的成功率。具体自己可以尝试。


个人认为,图片式验证码的防刷就是预防图形识别软件,感觉360刷票的认证登陆方式不错,就是给定一个名词,如:吉他,让登陆者点击选择图中所有的吉他,相信这种方式目前没有破解的途径,毕竟这里需要人工智能分析,至于有没有这样的开源库就得自己找了。


应该不会有人专门为了你这次投票而制作一个刷票机,那样的话成本会比较高的。


设备唯一ID 能得到就ok了~


现在还可以用 flashcookie ,对普通用户来说很难清除,可以做记录设备id用,对于一些专业的人,就不用考虑屏蔽了,如果有人搞你,是躲不掉的。


做微信里不错,用jssdk获取用户的openid,就可以了


人类已经无法阻止刷票行为了。。现在的人刷票都是加群,各种刷票群,然后各种人互刷。。


知己知彼,百战百胜

首先弄清用户为啥要刷,刷票对他有啥好处

我们当然会给刷票者设立门槛,但是只要刷票带来的收益大于付出的成本,就会存在刷票的可能性(墨菲定律)。

所以不存在完美的防止刷票的机制,而是根据具体的投票内容设置合适的投票成本。


禁止代理,然后用IP限制+复杂验证码限制,对于一般的投票是没问题的。


帐号登录投票,一个帐号只能投一次,这样就是不太方便了,得先弄个帐号登录。。。


我也觉得,要想完全防止刷票,是不可能的,我们能做的,只是尽量增加刷票方的成本,从而让他的付出大于刷票得到的成果,他自然而然就退却了!
除了ip、复杂验证码这些,我倒是比较推崇用户行为作为判断是否刷票的依据,再结合上面大家说的这些,能增加刷票的难度。
比如通过记录用户进入网站的过程,滚动条滚动到什么位置,鼠标在什么地方悬停多久,鼠标在什么地点击过,有无浏览其他页面,其他页面鼠标和滚动条的动作,都记录下来,判断符合正常人为投票的逻辑才能在票数上加1.


刷票行为,一直以来都是个难题,无法从根本上防止。

但是我们可以尽量减少刷票的伤害,比如:通过人为增加的逻辑限制。

基于 PHP,下面介绍防刷票的一些技巧:文章链接

1、使用CURL进行信息伪造

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, "http://localhost/2.php");
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-FORWARDED-FOR:8.8.8.8', 'CLIENT-IP:8.8.8.8'));
curl_setopt($ch, CURLOPT_REFERER, "http://localhost/ ");
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (compatible; MSIE 6.0; Windows NT 5.0)");
$out = curl_exec($ch); 
curl_close($ch);

2、验证码:采用非常复杂的验证码

确切的说验证码的出现不是针对于人,而是针对于机器。通过复杂度和识别难易度的控制来阻拦掉一部分刷票机,从而减少刷票的发生。但随着软件技术、识别技术的发展越来越多的验证码面对着先进的刷票软件也失去了其防范的作用、但是专业刷票机可以攻破。如果不用验证码,投票基本就歇菜了,验证码获取方式,采用异步加载,即点击输入框时,才去请求,投票成功后,删除验证码的 Session

3、限时投票

比如:从早8点至晚23 点

4、设置投票间隔

用户投票后,需要隔多长时间才能继续投。
很多投票站点基本上都有这个限制,但是对于更改 IP的攻击,就没办法了

5、投票结果展示:延迟展示,友好展示

页面上投票,JS 立马加1,但是刷新页面,不一定立马展示最新投票结果,返回状态给页面(感谢您的投票!或者 投票成功!至于有没有成功,另说了!)

6、扣量逻辑:常见于一些软件评选之类的投票

这是个杀手锏,后台跑脚本实时监控异常增长(刷票)的项,然后实施扣量逻辑
即对于这个项,投 10 票才算一票

7、Cookie:常用的手段。比较低级

投票后,在客户端写入 Cookie,下次投票时判断 Cookie 是否存在
但是,这种方式非常容易攻破,因为 Cookie 可删除

8、加密选项 ID:对一些投票选项的ID,进行随机加密

加密算法,加Salt,并且设置有效时间,比如5分钟内
服务器端进行解密并且验证

9、nginx限制链接数

ngx_http_limit_conn_module
ngx_http_limit_req_module
nginx_limit_speed_module

可以使用这三个模块来限制,不过这不是一个好的解决方法

10、iptables限制

/sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j DROP
/sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --set -j ACCEPT
/sbin/iptables -t filter -A INPUT -p tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 10 --connlimit-mask
 32 -j REJECT

具体脚本

#!/bin/bash
# Date: 2015-09-29
# # Author: cpz@erongtu.com
 
shopt -s -o nounset
export PATH=/usr/bin/:/bin
 
iptables_log="/tmp/iptables_conf.log"
 
/sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --rcheck --seconds 60 --hitcount 10 -j DROP
/sbin/iptables -A INPUT -p tcp --dport 80 --syn -m recent --name webpool --set -j ACCEPT
/sbin/iptables -t filter -A INPUT -p tcp --dport 80 --tcp-flags FIN,SYN,RST,ACK SYN -m connlimit --connlimit-above 10 --connlimit-mask 32 -j REJECT
 
while [ true ]; do
 
    #sleep 1
    for IP in `netstat -an | grep -i ':80 '|grep 'ESTAB' | awk '{print $5}' | cut -d : -f 1 | sort | uniq -c | awk '{if($1 > 30 && $2!="127.0.0.1" ) {print $2}}'`
    do
        /sbin/iptables -L -n  | grep  $IP >/dev/null || /sbin/iptables -A INPUT -p tcp --dport 80 -s $IP -j DROP
        echo "/sbin/iptables -A INPUT -p tcp  -s $IP -j DROP" >> ${iptables_log}
    done
done

投一票支付10元就可以了

【热门文章】
【热门文章】