【小鎮的技術天梯】刷票與防刷票的思考

【小鎮最近做的感動南通的投票活動目前有大概40w左右的投票記錄,小鎮通過篩選和排查,發現3000多條有刷票嫌疑的記錄,雖然說這些記錄對於總的投票活動來說基本上是九牛一毛,但是這觸及了程序猿的底線,你能刷票,就證明我的代碼有問題,小鎮必須排查和完善】

【雖然說通過驗證碼機制可以很好的防止刷票,但是如果有了驗證碼,誰還願意投票?本來點一下就可以投票的事情硬要輸入無聊的4個字符實乃是丟失參與度的最好方法哈哈,因爲有微信網頁授權的驗證機制,所以刷票不是非常容易就能實現的。小鎮這次來自己模仿一下如何刷票和反刷票。】

1、小鎮來刷票!

首先打開投票的網頁,咱可以看到下方的我要投票按鈕,點開瀏覽器的F12查看該按鈕的代碼,如下圖所示:


【在這裏,我們可以看到“我要投票”按鈕的id是woyaotoupiao,那麼就在js的文件中查找關於woyaotoupiao這個id的相關點擊事件,好,我們在下面找到了相應的代碼,如下圖所示:】


我們可以看到事件中是按鈕的點擊事件向toupiaoPHP.php文件發送了異步的post請求,其中的參數攜帶了uid,openid,和selfopenid。

【明眼人一眼就看到了刷票的希望,對啊,反正只要向這個php文件發送post請求就可以刷票了,至於toupiaoPHP.php文件裏面的驗證機制咱可以慢慢猜,但是隻通過這三個參數的可僞造性和不固定性就可以隨便刷啦!!】

這個發POST請求的不用小鎮教了吧。。基礎中的基礎,用php中的curl函數。然後攜帶參數就行啦,反正給個示例代碼大家看看就行啦。

這裏我們定義個要發送的數組對吧。


$post_array=("openid"=>"xxxx","selfopenid"=>"xxxx","uid"=>"xxxx");

然後定義一個curl的實例,恩,再加上一些參數對吧。好了,$url就是那個toupiaoPHP.php文件的地址就行了,然後就發送

  1.     $options = array(  
  2.         CURLOPT_RETURNTRANSFER => true,
  3.         CURLOPT_HEADER         => false,  
  4.         CURLOPT_POST           => true,  
  5.         CURLOPT_POSTFIELDS     => $post_array,  
  6.     );  
  7.   
  8.     $ch = curl_init($url);  
  9.     curl_setopt_array($ch$options);  

【然而,發送出去以後,回來的卻是禁止刷票四個大字!!爲啥呢,哦,變量的情況是可以排除的,爲啥呢,變量的情況是合法且合理的,那麼只有一種可能嘍,應該是裏面有着referer的判定,如下圖所示,我們再給curl的參數裏面加上相應的referer參數。】

curl_setopt ($ch,CURLOPT_REFERER,'xxxxxxx');

然後再發送請求,好了,返回過來投票成功。然後去看看投票的情況確實漲了一點投票。

【沒錯,這就是不用驗證碼的後果,其實,在這種情況下,不用驗證碼是很難很難防止刷票爬蟲啊之類的,但是,這是微信投票,微信有個值openid是確定且固定的,通過這個參數我們可以來防止刷票,像剛剛的情況我們可以僞造openid,但是如果一定要通過該投票頁面給toupiaoPHP.php發送post請求的話,那麼這個openid就是無法僞造的!因爲每次投票頁面都是實時獲取openid的。正是因爲這個原因,在toupiaoPHP的文件裏面纔會加入了referer的判定,確定post的請求是來自於投票頁面而不是隨便那臺服務器上面的請求,然而,referer也是可以僞造的哎!!真是蛋疼。】

【好了,怎麼解決呢!!就圍繞着打開投票頁面openid唯一確定性的定理來思考(暫且稱爲定理吧,哎嘿嘿),我們可以在投票頁面的php中隨即一個10位以上的字符串,並以openid爲鍵,該字符串爲鍵值存入Redis(不需要持久化的信息存redis最好了),然後post請求加一個參數,就是該隨即字符串,最後toupiaoPHP文件中在redis中查看該openid的鍵值,如果和發送的字符串是一樣的,就代表該投票有效。】

【結束了,想法還是很簡單的,但是損失了點性能。思考的過程不難,抓住什麼東西是確定不能僞造的特點來進行就可以了。】

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章