<![CDATA[ Quip comment spam and how to stop it.... - My Forums]]> https://forums.modx.com/thread/?thread=99601 <![CDATA[Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-538620
I have a client site with a blog using Articles and Quip as per the RTFM tutorial suggests with some mods. The site is a busy one and we are getting loads of spambot comment posts to the blog posts. I have tried to implement Rampart but it does not seem to do anything... Recaptcha works - but can only get the v1 recaptcha to work and that's not responsive which breaks the site on mobile views... Can't get Quip comments to work with recaptcha v2.... The noSpam hidden field doesn't seem to work either....

Any ideas on how to stop the spam posts!!!????


cheers

dubbs.]]>
dubbs Feb 22, 2016, 09:08 AM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-538620
<![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557103 Quote from: BobRay at Feb 28, 2018, 11:57 PM
I don't really know how Quip uses Recaptcha. I'll try to find time to take a look, but IIRC, the Quip code is tough to follow. AFAIK, Quip hasn't been updated for over 5 years and is no longer supported or under development..


Many thanks Bob - yeh, shame it seems to have been left to die - was a good tool to give MODx a blogging capacity - its a shame there are not more MODx Open Source enthusiasts out there to help keep things alive!]]>
dubbs Mar 01, 2018, 09:28 AM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557103
<![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557100
]]>
BobRay Feb 28, 2018, 11:57 PM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557100
<![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557092 https://modx.com/extras/package/recaptchav2) to work and validate the recaptcha is completed in Quip - but even when the recaptcha is succesfully checked - the validation fails and says it is not... any ideas on a fix?]]> dubbs Feb 28, 2018, 09:18 AM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557092 <![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557056 dubbs Feb 27, 2018, 10:24 AM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557056 <![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557048 Quote from: BobRay at Feb 26, 2018, 06:34 PM
Yes, it would have to change some. The changes described in the link I gave you above seem fairly straightforward
For someone with more PHP skills than me perhaps.. Any PHP whizkids fancy a challenge to adapt this to get it to work with the v2 recaptcha tool?]]>
dubbs Feb 26, 2018, 07:03 PM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557048
<![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557047 BobRay Feb 26, 2018, 06:34 PM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557047 <![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557031
<?php
/**
 * reCaptcha Integration
 *
 * Copyright 2009-2010 by Shaun McCormick <[email protected]>
 *
 * reCaptcha Integration is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option) any
 * later version.
 *
 * reCaptcha Integration is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
 * details.
 *
 * You should have received a copy of the GNU General Public License along with
 * reCaptcha Integration; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 * @package recaptcha
 */
/**
 * reCaptcha modX service class.
 *
 * Based off of recaptchalib.php by Mike Crawford and Ben Maurer. Changes include converting to OOP and making a class.
 *
 * @package recaptcha
 */
class reCaptcha {
    const OPT_API_SERVER = 'api_server';
    const OPT_API_SECURE_SERVER = 'api_secure_server';
    const OPT_API_VERIFY_SERVER = 'api_verify_server';
    const OPT_PRIVATE_KEY = 'privateKey';
    const OPT_PUBLIC_KEY = 'publicKey';
    const OPT_USE_SSL = 'use_ssl';

    function __construct(modX &$modx,array $config = array()) {
        $this->modx =& $modx;
        $this->modx->lexicon->load('quip:recaptcha');
        $this->config = array_merge(array(
            reCaptcha::OPT_PRIVATE_KEY => $this->modx->getOption('recaptcha.private_key',$config,''),
            reCaptcha::OPT_PUBLIC_KEY => $this->modx->getOption('recaptcha.public_key',$config,''),
            reCaptcha::OPT_USE_SSL => $this->modx->getOption('recaptcha.use_ssl',$config,false),
            reCaptcha::OPT_API_SERVER => 'http://www.google.com/recaptcha/api/',
            reCaptcha::OPT_API_SECURE_SERVER => 'https://www.google.com/recaptcha/api/',
            reCaptcha::OPT_API_VERIFY_SERVER => 'api-verify.recaptcha.net',
        ),$config);
    }

    /**
     * Encodes the given data into a query string format
     * @param $data - array of string elements to be encoded
     * @return string - encoded request
     */
    protected function qsencode($data) {
        $req = '';
        foreach ($data as $key => $value) {
            $req .= $key . '=' . urlencode( stripslashes($value) ) . '&';
        }

        // Cut the last '&'
        $req=substr($req,0,strlen($req)-1);
        return $req;
    }

    /**
     * Submits an HTTP POST to a reCAPTCHA server
     * @param string $host
     * @param string $path
     * @param array $data
     * @param int port
     * @return array response
     */
    protected function httpPost($host, $path, array $data = array(), $port = 80) {
        $data['privatekey'] = $this->config[reCaptcha::OPT_PRIVATE_KEY];
        $req = $this->qsencode($data);

        $http_request  = "POST $path HTTP/1.0\r\n";
        $http_request .= "Host: $host\r\n";
        $http_request .= "Content-Type: application/x-www-form-urlencoded;\r\n";
        $http_request .= "Content-Length: " . strlen($req) . "\r\n";
        $http_request .= "User-Agent: reCAPTCHA/PHP\r\n";
        $http_request .= "\r\n";
        $http_request .= $req;

        $response = '';
        if(false == ($fs = @fsockopen($host, $port, $errno, $errstr, 10))) {
            return 'Could not open socket';
        }

        fwrite($fs, $http_request);
        while (!feof($fs)) {
            $response .= fgets($fs, 1160); // One TCP-IP packet
        }
        fclose($fs);
        $response = explode("\r\n\r\n", $response, 2);

        return $response;
    }
    
    /**
     * Gets the challenge HTML (javascript and non-javascript version).
     * This is called from the browser, and the resulting reCAPTCHA HTML widget
     * is embedded within the HTML form it was called from.
     * @param string $theme The theme to use
     * @param string $error The error given by reCAPTCHA (optional, default is null)
     * @param boolean $use_ssl Should the request be made over ssl? (optional, default is false)

     * @return string - The HTML to be embedded in the user's form.
     */
    public function getHtml($theme = 'clean',$error = null) {
        if (empty($this->config[reCaptcha::OPT_PUBLIC_KEY])) {
            return $this->error($this->modx->lexicon('recaptcha.no_api_key'));
        }

        /* use ssl or not */
        $server = !empty($this->config[reCaptcha::OPT_USE_SSL]) ? $this->config[reCaptcha::OPT_API_SECURE_SERVER] : $this->config[reCaptcha::OPT_API_SERVER];

        $errorpart = '';
        if ($error) {
           $errorpart = "&error=" . $error;
        }
        $opt = array(
            'theme' => $theme,
            'lang' => $this->modx->getOption('cultureKey',null,'en'),
        );
        return '<script type="text/javascript">var RecaptchaOptions = '.$this->modx->toJSON($opt).';</script><script type="text/javascript" src="'. $server . 'challenge?k=' . $this->config[reCaptcha::OPT_PUBLIC_KEY] . $errorpart . '"></script>
        <noscript>
                <iframe src="'. $server . 'noscript?k=' . $this->config[reCaptcha::OPT_PUBLIC_KEY] . $errorpart . '" height="300" width="500" frameborder="0"></iframe><br/>
                <textarea name="recaptcha_challenge_field" rows="3" cols="40"></textarea>
                <input type="hidden" name="recaptcha_response_field" value="manual_challenge"/>
        </noscript>';
    }

    protected function error($message = '') {
        $response = new reCaptchaResponse();
        $response->is_valid = false;
        $response->error = $message;
        return $message;
    }

    /**
      * Calls an HTTP POST function to verify if the user's guess was correct
      * @param string $remoteip
      * @param string $challenge
      * @param string $response
      * @param array $extra_params an array of extra variables to post to the server
      * @return ReCaptchaResponse
      */
    public function checkAnswer ($remoteIp, $challenge, $responseField, $extraParams = array()) {
        if (empty($this->config[reCaptcha::OPT_PRIVATE_KEY])) {
            return $this->error($this->modx->lexicon('recaptcha.no_api_key'));
        }

        if (empty($remoteIp)) {
            return $this->error($this->modx->lexicon('recaptcha.no_remote_ip'));
        }

        //discard spam submissions
        if (empty($challenge) || empty($responseField)) {
            return $this->error($this->modx->lexicon('recaptcha.empty_answer'));
        }

        $verifyServer = $this->config[reCaptcha::OPT_API_VERIFY_SERVER];
        $response = $this->httpPost($verifyServer,"/verify",array (
            'remoteip' => $remoteIp,
            'challenge' => $challenge,
            'response' => $responseField,
        ) + $extraParams);

        $answers = explode("\n",$response[1]);
        $response = new reCaptchaResponse();

        if (trim($answers[0]) == 'true') {
            $response->is_valid = true;
        } else {
            $response->is_valid = false;
            $response->error = $answers [1];
        }
        return $response;
    }

    /**
     * gets a URL where the user can sign up for reCAPTCHA. If your application
     * has a configuration page where you enter a key, you should provide a link
     * using this function.
     * @param string $domain The domain where the page is hosted
     * @param string $appname The name of your application
     */
    public function getSignupUrl ($domain = null, $appname = null) {
        return "http://recaptcha.net/api/getkey?" .  $this->qsencode(array ('domain' => $domain, 'app' => $appname));
    }

    protected function aesPad($val) {
        $block_size = 16;
        $numpad = $block_size - (strlen ($val) % $block_size);
        return str_pad($val, strlen ($val) + $numpad, chr($numpad));
    }

    /* Mailhide related code */
    protected function aesEncrypt($val,$ky) {
        if (!function_exists("mcrypt_encrypt")) {
            return $this->error($this->modx->lexicon('recaptcha.mailhide_no_mcrypt'));
        }
        $mode=MCRYPT_MODE_CBC;
        $enc=MCRYPT_RIJNDAEL_128;
        $val= $this->aesPad($val);
        return mcrypt_encrypt($enc, $ky, $val, $mode, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0");
    }


    protected function mailhideUrlbase64 ($x) {
        return strtr(base64_encode ($x), '+/', '-_');
    }

    /* gets the reCAPTCHA Mailhide url for a given email, public key and private key */
    public function mailhideUrl($email) {
        if (empty($this->config[reCaptcha::OPT_PUBLIC_KEY]) || empty($this->config[reCaptcha::OPT_PRIVATE_KEY])) {
            return $this->error($this->modx->lexicon('recaptcha.mailhide_no_api_key'));
        }

        $ky = pack('H*',$this->config[reCaptcha::OPT_PRIVATE_KEY]);
        $cryptmail = $this->aesEncrypt($email, $ky);
        return 'http://mailhide.recaptcha.net/d?k='
            . $this->config[reCaptcha::OPT_PUBLIC_KEY]
            . '&c=' . $this->mailhideUrlbase64($cryptmail);
    }

    /**
     * gets the parts of the email to expose to the user.
     * eg, given johndoe@example,com return ["john", "example.com"].
     * the email is then displayed as [email protected]
     */
    public function mailhideEmailParts ($email) {
        $arr = preg_split("/@/", $email);

        if (strlen($arr[0]) <= 4) {
            $arr[0] = substr($arr[0], 0, 1);
        } else if (strlen ($arr[0]) <= 6) {
            $arr[0] = substr($arr[0], 0, 3);
        } else {
            $arr[0] = substr($arr[0], 0, 4);
        }
        return $arr;
    }

    /**
     * Gets html to display an email address given a public an private key.
     * to get a key, go to:
     *
     * http://mailhide.recaptcha.net/apikey
     */
    public function mailhideHtml($email) {
        $emailparts = $this->mailhideEmailParts($email);
        $url = $this->mailhideUrl($email);

        return htmlentities($emailparts[0]) . "<a href='" . htmlentities ($url) .
            "' onclick=\"window.open('" . htmlentities ($url) . "', '', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=500,height=300'); return false;\" title=\"Reveal this e-mail address\">...</a>@" . htmlentities ($emailparts [1]);
    }


}

/**
 * A reCaptchaResponse is returned from reCaptcha::check_answer()
 */
class reCaptchaResponse {
    public $is_valid;
    public $error;
}

]]>
dubbs Feb 26, 2018, 01:55 PM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it?page=2#dis-post-557031
<![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it#dis-post-557030 Quote from: BobRay at Jun 21, 2016, 12:38 PM
This looks like a pretty good explanation of the necessary changes to migrate from V1 to V2: https://blog.sendsafely.com/migrating-to-googles-nocaptcha-recaptcha . It might not require changes to the code of MODX or any MODX extras.

Thanks Bob - not sure how this relates to getting it to work in Quip though?]]>
dubbs Feb 26, 2018, 01:44 PM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it#dis-post-557030
<![CDATA[Re: Quip comment spam and how to stop it....]]> https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it#dis-post-542666 https://blog.sendsafely.com/migrating-to-googles-nocaptcha-recaptcha . It might not require changes to the code of MODX or any MODX extras.]]> BobRay Jun 21, 2016, 12:38 PM https://forums.modx.com/thread/99601/quip-comment-spam-and-how-to-stop-it#dis-post-542666