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

标签 javascript php magento-1.9 recaptcha

我实现了 reCaptcha。单击“我不是机器人”复选框后,将从 google 生成一个 token 。

客户端(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将 token 发送到我的服务器并在那里验证它,如下所示:

服务器端(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的输出

enter image description here

如果检查成功,则返回成功,否则返回失败

但这就足够了吗?如果攻击者使用像 burpsuite 这样的 HTTP 代理将响应更改为成功怎么办?那么他就可以绕过我的检查并始终通过吗?还是我错了?

最佳答案

它使用 key 对来加密/解密信息。所以它发送的信息是加密的。这就是为什么它不能被篡改,但是当然,这意味着您必须确保私钥不被盗。

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

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

客户端和服务器之间的通信也应该使用 HTTPS,以避免一些更简单的中间人 (MITM) 问题。然而,总是有可能有人成为代理人,这就是大多数 MITM 的工作方式,在这种情况下,无论你在做什么,MITM 都可以改变。

但是,MITM 无法做的一件事是为最终目的地创建有效的证书。从这个意义上说,这是一种保护,但许多人在每次连接到网站时都不会验证证书。不过,MITM 的一种技术是不向您提供 HTTPS,只有他和您的服务器会使用 HTTPS,而客户端将保留在 HTTP 上。尽管您的代码可以检测到此类情况,但显然 MITM 也可以更改该代码。同样,使用 Http-OnlySecure 设置 cookie 可以增强安全性,但这也可能被 MITM 拦截。

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

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

关于javascript - 如何在服务器端验证 google reCaptcha?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51723157/

相关文章:

php - 如何取消在mysql中重复键更新时未更新的列

mysql - Magento 1.9 联接查询

php - Magento 1.9 创建新的 Hello World 模块

java - 对 JAVA Servlet 的 REST 请求

javascript - 在 Aurelia 中访问 DOM 元素

php - 选中所有复选框并更改所有 Jquery 的颜色

php - 如何向多个渲染的 URL 添加参数?

xml - 将自定义字段添加到 paypal 模块 magento 1.9

javascript - 如何在使用 "new"构造函数的同时触发函数?

javascript - Azure Function - 处理消息而不输出结果会发生什么?