代码之家  ›  专栏  ›  技术社区  ›  Black

如何在服务器端验证google reCaptcha?

  •  -1
  • Black  · 技术社区  · 6 年前

    我是雷帕查。在“我不是机器人”复选框被点击后,一个令牌将从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将令牌发送到服务器,并在那里进行验证,如下所示:

        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的输出

    enter image description here

    它回来了 success 如果检查成功,否则 fail

    成功 ? 那他就可以绕过我的支票一直通过了?还是我错了?

    2 回复  |  直到 6 年前
        1
  •  1
  •   Alexis Wilke    6 年前

    它使用密钥对信息进行加密/解密。所以它发送的信息是加密的。这就是为什么它不能调和,但当然,这意味着你必须确保没有得到私钥被盗。

    在那里,服务器知道并将状态保存在其存储中,因此,如果客户机试图在状态为“失败”时将其用作“成功”,服务器将知道,无论发生什么。因此,对于黑客来说,更改客户端的值不太可能有多大作用,当然,这将取决于您的代码。如果您使用该reCAPTCHA登录用户,那么很明显,如果reCAPTCHA返回“fail”,那么登录尝试将在服务器端失败。因此,无论客户是否被告知“成功”,它仍然不会被登录。客户机永远不应该是这样一个状态的守护者,因为它不可信任(它可能总是有受污染的数据)

    它的工作方式类似于使用HTTPS在浏览器和服务器之间执行的操作。

    Http-Only Secure 可以增强安全性,但也可以被MITM拦截。

    由于MITM可以完全更改您的脚本,因此在客户端几乎没有任何操作可以帮助您检测此类问题,而在服务器端,您将收到类似于客户端发送给您的点击。所以再说一次,没有真正的方法来检测MITM。

    There is a post 这就是在问这样一个问题:我能从服务器端检测到一个MITM吗?这不是不可能,但相当棘手。有一些解决方案是由普通HTTP解决方案的新实现/扩展提供的,但是这些解决方案需要一个连接到不同系统的附加应用程序,并且没有理由在有足够多的人使用这些解决方案之后,MITM也不能代理这些解决方案。

        2
  •  0
  •   matiit    6 年前

    结果来自一个由Google拥有的URL。