簡體   English   中英

如何在服務器端驗證Google reCaptcha?

[英]How to validate google reCaptcha on server side?

我實現了reCaptcha。 單擊“我不是機器人”復選框后,就會從Google生成令牌。

客戶端(js)

    function checkCaptchaAndSubscribe(thisContext)
    {
        var captchaResponse = grecaptcha.getResponse();

        if (captchaResponse == "") {
            $captchaRequired.css('display', 'block');
            return false;
        }

        grecaptcha.reset();
        $captchaRequired.css('display', 'none');

        jQuery.ajax({
            url: "/black_newsletter2go/index/verify",
            method: "POST",
            async: "true",
            data: {
                recaptchaResponse: captchaResponse
            },
            success: function(response) {

                $statusContainer.show();

                if (response != "success") {
                    $status.html("<h2 class='nl2go_h2'>Die Captcha Validierung ist fehlgeschlagen!</h2>");
                    return false;
                }

                subscribe(thisContext);
            }
        });
    }

我使用ajax將令牌發送到服務器,並在此進行驗證:

服務器端(php):

    public function verifyAction()
    {
        $captchaResponse = $this->getRequest()->getParam('recaptchaResponse');

        if (!isset($captchaResponse) || empty($captchaResponse)) {
            return "captcha response is empty";
        }

        $secretKey = Mage::Helper("recaptcha")->getSecretKey();

        $url = 'https://www.google.com/recaptcha/api/siteverify';
        $data = array(
            'secret' => $secretKey,
            'response' => $captchaResponse,
        );

        // use key 'http' even if you send the request to https://...
        $options = array(
            'http' => array(
                'header'  => "Content-type: application/x-www-form-urlencoded\r\n",
                'method'  => 'POST',
                'content' => http_build_query($data)
            )
        );

        $context  = stream_context_create($options);

        $result = file_get_contents($url, false, $context);
        $result = json_decode($result);

        //var_dump($result);
        //exit();

        if ($result->success
                && (strpos(Mage::getBaseUrl(), $result->hostname) !== false)) {
            echo "success";
        } else {
            echo "fail";
        }
    }

這是對象$ result的輸出

在此處輸入圖片說明

它返回success如果檢查是全成,否則fail

但是夠了嗎? 如果攻擊者使用burpsuite這樣的HTTP代理更改success響應,該怎么辦? 然后他可以繞過我的支票並始終通過? 還是我錯了?

它使用密鑰對來加密/解密信息。 因此,它以加密方式發送信息。 這就是為什么不能對其進行調整,但是,當然,這意味着您必須確保不要使私鑰被盜。

服務器知道那里的狀態並將其保存在其存儲中,因此,如果客戶端在狀態“失敗”時嘗試將其用作“成功”,則服務器將知道,無論如何。 因此,對於黑客來說,改變客戶端的價值的可能性不大,這當然取決於您的代碼。 如果使用該reCAPTCHA登錄用戶,則很明顯,如果reCAPTCHA返回“失敗”,則登錄嘗試將在服務器端失敗。 因此,無論客戶端是否被告知“成功”,它仍然不會登錄。客戶端永遠不應該成為這種狀態的守護者,因為它不能被信任(它總是會污染數據)。

它的工作方式類似於您使用HTTPS在瀏覽器和服務器之間進行的操作。

客戶端和服務器之間的通信也應該使用HTTPS,以避免出現一些中間人(MITM)問題。 但是,總是有可能有人成為代理,這就是大多數MITM的工作方式,在這種情況下,MITM可以更改您所做的任何事情。

但是,MITM不能做的一件事就是為最終目的地創建有效的證書。 從這個意義上說,這是一種保護,但是許多人每次連接到網站時都不會驗證證書。 但是,MITM的一種技術是不給您HTTPS,只有他和您的服務器將使用HTTPS,而客戶端仍將使用HTTP。 盡管您的代碼可以檢測到這種情況,但MITM顯然也可以更改該代碼。 同樣,設置具有Http-OnlySecure的cookie可以增強安全性,但是MITM也可以攔截該cookie。

由於MITM可以完全更改您的腳本,因此在客戶端方面您幾乎無能為力,無助於檢測到此類問題,而在服務器端,您將收到與客戶端發送給您的內容相似的點擊。 再次重申,沒有檢測MITM的真正方法。

有一則帖子問了這個問題:我可以從服務器端檢測到MITM嗎? 這不是不可能,但是很棘手。 新的實現/擴展是對常規HTTP解決方案的解決方案,但是這些解決方案需要連接到不同系統的其他應用程序,並且沒有足夠的理由,一旦有足夠的人使用MITI也無法將其替代解決方案。

結果來自Google擁有的URL。 如果用戶篡改了發送到您的PHP腳本的內容-則Google Web服務將返回失敗信息,您將不會通過此類請求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM