Invisible reCAPTCHA is not working behind proxy server

2,398 views
Skip to first unread message

igor....@ff.uns.ac.rs

unread,
Jun 15, 2017, 6:23:32 AM6/15/17
to reCAPTCHA
Hi,
We are using OJS (Open Journal System) for hosting our online journals and as an option we have (re)captcha as protection. Currently this protection doesn't work because recaptcha doesn't respect proxy configuration (our network is protected by proxy server). In earlier versions this was solved by modifying controller file:


function _recaptcha_http_post($host, $path, $data, $port = 80) {
    $proxy_host
= 'PROXY-HOST';
    $proxy_port
=PROXY-PORT;
    $proxy_username
='PROXY-USERNAME';
    $proxy_password
='PROXY-PASSWORD';


    $req
= _recaptcha_qsencode ($data);


    $http_request  
= "POST http://$host$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";


   
if (!empty($proxy_username)) {
        $auth_string
= base64_encode($proxy_username . ($proxy_password != '' ? ":{$proxy_password}" : ''));
        $http_request
.= "Connection: close\r\n";
       
if ( !empty($auth_string ) ) $http_request .= "Proxy-Authorization: Basic {$auth_string}\r\n";
   
}


    $http_request
.= "\r\n";
    $http_request
.= $req;


    $response
= '';
   
if( false == ( $fs = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 10) ) ) {
       
die ('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;



But now recaptcha controller looks different and we are unable to pass it trough proxy server (we get validation error)

<?php
/**
 * @file classes/form/validation/FormValidatorReCaptcha.inc.php
 *
 * Copyright (c) 2014-2017 Simon Fraser University
 * Copyright (c) 2000-2017 John Willinsky
 * Distributed under the GNU GPL v2. For full terms see the file docs/COPYING.
 *
 * @class FormValidatorReCaptcha
 * @ingroup form_validation
 *
 * @brief Form validation check reCaptcha values.
 */

define
('RECAPTCHA_RESPONSE_FIELD', 'g-recaptcha-response');
define
('RECAPTCHA_HOST', 'https://www.google.com');
define
("RECAPTCHA_PATH", "/recaptcha/api/siteverify");
class FormValidatorReCaptcha extends FormValidator {
 
/** @var string */
 
var $_userIp;
 
/**
 * Constructor.
 * @param $form object
 * @param $userIp string IP address of user request
 * @param $message string Key of message to display on mismatch
 */

 
function __construct(&$form, $userIp, $message) {
 parent
::__construct($form, RECAPTCHA_RESPONSE_FIELD, FORM_VALIDATOR_REQUIRED_VALUE, $message);
 $this
->_userIp = $userIp;
 
}

 
//
 
// Public methods
 
//
 
/**
 * @see FormValidator::isValid()
 * Determine whether or not the form meets this ReCaptcha constraint.
 * @return boolean
 */

 
function isValid() {
 $privateKey
= Config::getVar('captcha', 'recaptcha_private_key');
 
if (is_null($privateKey) || empty($privateKey)) {
 
return false;
 
}
 
if (is_null($this->_userIp) || empty($this->_userIp)) {
 
return false;
 
}
 $form
=& $this->getForm();
 
// Request response from recaptcha api
 $requestOptions
= array(
 
'http' => array(
 
'header' => "Content-Type: application/x-www-form-urlencoded;\r\n",
 
'method' => 'POST',
 
'content' => http_build_query(array(
 
'secret' => $privateKey,
 
'response' => $form->getData(RECAPTCHA_RESPONSE_FIELD),
 
'remoteip' => $this->_userIp,
 
)),
 
),
 
);
 $requestContext
= stream_context_create($requestOptions);
 $response
= file_get_contents(RECAPTCHA_HOST . RECAPTCHA_PATH, false, $requestContext);
 
if ($response === false) {
 
return false;
 
}
 $response
= json_decode($response, true);
 
// Unrecognizable response from Google server
 
if (isset($response['success']) && $response['success'] === true) {
 
return true;
 
} else {
 
if (isset($response['error-codes']) && is_array($response['error-codes'])) {
 $this
->_message = 'common.captcha.error.' . $response['error-codes'][0];
 
}
 
return false;
 
}
 
}
}

?>

Could someone please help me with some advice, I was looking trough Internet for solution but didn't find any relevant answer? 



igor....@ff.uns.ac.rs

unread,
Jun 15, 2017, 6:28:09 AM6/15/17
to reCAPTCHA
I have try to use recaptcha v2 but results are same, not passing verification.

Mickaël THOMAS

unread,
Jun 15, 2017, 7:35:24 PM6/15/17
to reCAPTCHA
You can easily set a proxy globally with stream_context_set_default :

$proxy_host = 'PROXY-HOST';
$proxy_port
= PROXY-PORT;
$proxy_username
= 'PROXY-USERNAME';
$proxy_password
= 'PROXY-PASSWORD';

$options
= array('http' => array(
   
'proxy' => "tcp://$proxy_host:$proxy_port",
   
'request_fulluri' => true,
   
'header' => 'Proxy-Authorization: Basic ' . base64_encode("$proxy_username:$proxy_password")
));

stream_context_set_default
($options);


Reply all
Reply to author
Forward
0 new messages