[分享] 垃圾留言判斷,隱藏驗證碼的 NoSpamNX class PART2

分類: 技術分享 作者: daniel

27 8 月 2009

感謝上一篇文章中前輩們的熱心回覆;垃圾留言果然是大家心中的痛啊(噗)~雖然 CAPTCHA 可以透過各式各樣的 OCR 破解(最新版的 JDownloader 也已經能忽略大部分免費空間所用的圖像辨識...扯遠了),不過它仍是目前阻擋機器人最直接也最簡單的解決方案;當然更複雜的 CAPTCHA 還是能夠達到阻擋的目的,但是使用 CAPTCHA 的方式對使用者來說就已經是不友善了。

後來在討論中 Jace 提到,其實 SESSION 是有可能被機器人知道的;所以我後來綜合了 fillano 提供的演算法概念,稍微改良了一下之前的 NoSpamNX class。利用隨機產生的隱藏欄位順序,用不同的演算法再對隱藏欄位的數值作編碼;讓 SESSION 內存的未編碼的值,與 POST 過來的已編碼的值不一樣。最後再將 SESSION 內存的值編碼,與 POST 的已編碼的值作比較,判斷留言的使用者是不是機器人。

SESSION 紀錄的值是未編碼的值,但在產生隱藏欄位時,input 的值是已經編碼過後的值

/**
 * 建立隱藏欄位 HTML;利用隱藏欄位先後順序不同,使用 md5 or sha1 編碼
 * 
 */
public function addHiddenFields()
{
    $nospamnx = $_SESSION[$this->_sessionName];

    if (1 === rand(1,2)) {
        return '<input type="text" name="nospamnx['.$nospamnx['nospamnx-1'].']" value="" class="locktross" /><input type="text" name="nospamnx['.$nospamnx['nospamnx-2'].']" value="'.md5($nospamnx['nospamnx-2-value']).'" class="locktross" />';
    } else {
        return '<input type="text" name="nospamnx['.$nospamnx['nospamnx-2'].']" value="'.sha1($nospamnx['nospamnx-2-value']).'" class="locktross" /><input type="text" name="nospamnx['.$nospamnx['nospamnx-1'].']" value="" class="locktross" />';
    }
}

驗證時根據 POST 過來的 nospamnx 順序不同,以不同的演算法編碼後再做比較

// 根據 POST 過來的值順序不同,以 md5 or sha1 判斷
if ($nospamnx['nospamnx-1'] == current(array_keys($postData))) {
    $encode_value = md5($nospamnx['nospamnx-2-value']);
} else {
    $encode_value = sha1($nospamnx['nospamnx-2-value']);
}
if ($postData[$nospamnx['nospamnx-2']] != $encode_value) {
    return false;
}

最後提供範例程式下載,分為一般 POST 與 AJAX 二種方式。

我要留言

關於這裡

這個部落格分享了哇寶在電子商務領域的技術及資訊,希望能讓更多人一起為台灣的網路產業加油。