reCAPTCHA V2 Failing On Server Side Validation - javascript

My reCaptcha V2 "I'm not a robot" is failing on the server side.
It seems to be failing at:
post_captcha($_POST['g-recaptcha-response'])
Both the public & pvt key are correct and on the correct domain.
It's been 3 hours since I've created the reCAPTCHA so maybe it takes a while to process my domain through the system? I'm not sure....
Here is the HTML:
<html>
<head>
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
</head>
<body>
<form action="contact-form.php" method="POST">
<div class="g-recaptcha" data-sitekey="PUBLIC KEY"></div>
<br/>
<input type="submit" value="Submit">
</form>
</body>
</html>
Here is the PHP:
<?php
// Checks if form has been submitted
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
function post_captcha($user_response) {
$fields_string = '';
$fields = array(
'secret' => 'PVT KEY',
'response' => $user_response
);
foreach($fields as $key=>$value)
$fields_string .= $key . '=' . $value . '&';
$fields_string = rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify');
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
// Call the function post_captcha
$res = post_captcha($_POST['g-recaptcha-response']);
if (!$res['success']) {
// What happens when the CAPTCHA wasn't checked
echo '<p>Please go back and make sure you check the security CAPTCHA box.</p><br>';
} else {
echo 'success';
}
}
?>
Any help will be greatly appreciated!
Thank you.

Long time no answer. The issue was because of my web service provider having limitations on the shared server I was subscribe to e.g. not being able to edit php.ini config file.
Solution: don't use a shared server!

Related

I am trying to understand how an licence key will work and how it can be bypassed to validate in php

I am trying to understand the below code how exactly it was verifying the license key and can it be bypassed in php file its self to put self license key and get verified
<?php
session_start();
if (!function_exists('curl_init')) {
die('cURL is not available on your server! Please enable cURL to continue the installation. You can read the documentation for more information.');
}
function currentUrl($server)
{
$http = 'http';
if (isset($server['HTTPS'])) {
$http = 'https';
}
$host = $server['HTTP_HOST'];
$requestUri = $server['REQUEST_URI'];
return $http . '://' . htmlentities($host) . '/' . htmlentities($requestUri);
}
$current_url = currentUrl($_SERVER);
if (isset($_POST["btn_purchase_code"])) {
$_SESSION["purchase_code"] = $_POST['purchase_code'];
$response = "";
$url = "http://jobsearchers.in/api/license?purchase_code=" . $_POST['purchase_code'] . "&domain=" . $current_url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
if (empty($response)) {
$url = "http://jobsearchers/api/license?purchase_code=" . $_POST['purchase_code'] . "&domain=" . $current_url;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
}
$data = json_decode($response);
if (!empty($data)) {
if ($data->status == "300" || $data->status == "400") {
$_SESSION["error"] = "Invalid purchase code!";
} else {
$_SESSION["status"] = $data->status;
$_SESSION["license_code"] = $data->license_code;
header("Location: folder-permissions.php");
exit();
}
} else {
$_SESSION["error"] = "Invalid purchase code!";
}
}
?>
I tried removing the curl and place my own key in $data place like $data = 123456789 and tried to validate it doesn't work.
In that snippet of code, the application sends an HTTP request with the purchase_code and gets back the license_code.
This is better than hard-coding the license code on the device to avoid users sharing license codes.
Let's assume that the license_code returned does not get verified, in that case you can just change the script to do the following:
<?php
session_start();
if (isset($_POST["btn_purchase_code"])) {
$_SESSION["purchase_code"] = $_POST['purchase_code'];
$_SESSION["status"] = 200;
$_SESSION["license_code"] = "fake_license_code";
header("Location: folder-permissions.php");
exit();
}
?>
However, what the above code does is it only spoofs the response of the server, there usually is some sort of "correlation" between your purchase_code and your license_code that only the devs know, and they use that knowledge to verify that your license code matches the purchase code.
If you are doing this for malicious reasons, big shame, but if you're doing this to foolproof your application from being cracked, then you have to figure out a way to locally verify the "license_code" and make sure it's a valid code sent by the server, this can be done by signing the code with a private key from the server, which would make it impossible to replicate.
My favorite way of creating unique verifiable tokens or license codes, is JWT.
You can use JWT to create a token that contains a timestamp, purchase_code and other information, then sign it using a private key, that makes it impossible to replicate. The client can verify the isser through a public key.
TL;DR: The above snippet will only work if no extra steps are done to verify the license_code, which is unlikely. A good step to verify that the license_code is one shared by the server is to sign it with a private key.

Login to site with PHP cURL

I'm trying login to a remote site, by having curl to the login form.
I want to redirect to another subdomain and get content.
The code I have doesn't seem to work and only tries to show the main page of the site.
<?php
$username = 'user';
$password = 'pass';
$loginUrl = 'https://site_url';
//init curl
$ch = curl_init();
//Set the URL to work with
curl_setopt($ch, CURLOPT_URL, $loginUrl);
// ENABLE HTTP POST
curl_setopt($ch, CURLOPT_POST, 1);
//Set the post parameters
curl_setopt($ch, CURLOPT_POSTFIELDS, 'user='.$username.'&password='.$password);
//Handle cookies for the login
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
curl_setopt ($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
//Setting CURLOPT_RETURNTRANSFER variable to 1 will force cURL
//not to print out the results of its query.
//Instead, it will return the results as a string return value
//from curl_exec() instead of the usual true/false.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute the request (the login)
$store = curl_exec($ch);
//the login is now done and you can continue to get the
//protected content.
//set the URL to the protected file
curl_setopt($ch, CURLOPT_URL, 'https://site_url/statistics');
//execute the request
$content = curl_exec($ch);
curl_close($ch);
//save the data to disk
file_put_contents('~/file.txt', $content);
?>
Does it have to be via cURL?
Have you considered leveraging a library like Guzzle?
They have good documentation that covers scenarios as you have described.
https://docs.guzzlephp.org/en/stable/quickstart.html#post-form-requests
Something like the below but could be laid out better
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
$client = new Client(['base_uri' => 'https://url_site/', 'cookies' => true]);
// Login
try {
$client->request(
'POST',
'login/',
[
'form_params' => [
'username' => $username,
'password' => $password,
],
]
);
} catch (BadResponseException $e) {
echo "Error Logging On for User {$username}";
exit;
}
// Navigate
$response = $client->request('GET', '/statistics');
$content = $response->getBody()->getContents();
file_put_contents('~/file.txt', $content);

Can not get data from AJAX request to the Coinhive API

I recently tried to get the data from a Json API and post that back to a table in html.
I tried to do this from: https://api.coinhive.com/user/balance?name=username&secret=mysecret
It does show me: {"success":true,"name":"*user*","total":49152,"withdrawn":0,"balance":* a value *}
But I want to let my users push a button which will load the balance value to a table in their own user portal.
I got the user portal setup with all the mysqlvalues, But i can't manage to get the jsonpart to work.
Can anyone please help me?
Thanks in common,
Dennis.
edit:
I tried the following:
<html lang="en">
<head>
<title>JavaScript - read JSON from URL</title>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
</head>
<body>
<div class="mypanel"></div>
<script>
$.getJSON('https://api.coinhive.com/user/balance?name=username&secret=mysecret', function(data) {
var text = `Balance: ${data.balance}<br>`
$(".mypanel").html(text);
});
</script>
</body>
</html>
And I also tried:
function setup() {
loadJSON("https://api.coinhive.com/user/balance?name=username&secret=mysecret", gotData);
}
function gotData(data) {
alert(data);
}
And that isn't working.
What am I doing wrong?
figured it out!
The JSON request:
<?php
$url = 'the api url';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_TIMEOUT, 5);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/x-www-form-urlencoded"
));
$data = curl_exec($ch);
curl_close($ch);
$result = json_decode($data, true);
?>
The postback to the end user:
<span id="test" style="color:white"><?php
if (isset($data))
{
echo $result['balance'];
}
else
{
echo 'damn';
}
?></span>
I decided to go with php and kind of ditch the html getjson part.
Client side requests to the Coinhive HTTP API are restricted by CORS rules:
From API documentation:
You should never call the Coinhive HTTP API from the client side.

How to reset Google reCaptcha?

Here is my PHP Code:
function post_captcha($user_response) {
$fields_string = '';
$fields = array(
'secret' => '',
'response' => $user_response
);
foreach($fields as $key=>$value)
$fields_string .= $key . '=' . $value . '&';
$fields_string = rtrim($fields_string, '&');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://www.google.com/recaptcha/api/siteverify');
curl_setopt($ch, CURLOPT_POST, count($fields));
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, True);
$result = curl_exec($ch);
curl_close($ch);
return json_decode($result, true);
}
$res = post_captcha($_POST['g-recaptcha-response']);
if (!$res['success']) {
die('MF005');
} else {
if ($mail->send()) {
$send_arEmail = $autoresponder->Send();
}}
and here is my JavaScript code:
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
<script>
function onSubmit(token) {
document.getElementById("i-recaptcha").submit();
}
</script>
This is my captcha:
<div class="g-recaptcha" data-sitekey="" ></div>
and this is button submit:
<button class="button rounded" type="submit" data-callback="onSubmit">Send</button>
This is also my form id:
<form id="i-recaptcha">
This above function is working, but after submit form, still captcha is checked, I want to reset it to unchecked once user click on submit button.
You can use it like this. It's based on version.
Version 3
grecaptcha.ready(function() {
grecaptcha.execute('SITE_KEY', {action: 'homepage'}).then(function(token){
$('#token').val(token);
});
});
Version 2
grecaptcha.reset();
Version 1
Recaptcha.reload();

how to php get meta tag from external url Without reload page

I have many inputs on my page like
user name
URL
Des
keywords
bl bl
I need to get the meta tags from an URL the user enters in the URL input with JavaScript or Ajax
because I need not to reload the page.
I know I can use get_meta_tags('single_URL');, but i need to get the metas from the URL on submit :
Here's my code :
function file_get_contents_curl($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
$html = file_get_contents_curl("http://example.com/");
//parsing begins here:
$doc = new DOMDocument();
#$doc->loadHTML($html);
$nodes = $doc->getElementsByTagName('title');
//get and display what you need:
$title = $nodes->item(0)->nodeValue;
$metas = $doc->getElementsByTagName('meta');
for ($i = 0; $i < $metas->length; $i++)
{
$meta = $metas->item($i);
if($meta->getAttribute('name') == 'description')
$description = $meta->getAttribute('content');
if($meta->getAttribute('name') == 'keywords')
$keywords = $meta->getAttribute('content');
}
echo "Title: $title". '<br/><br/>';
echo "Description: $description". '<br/><br/>';
echo "Keywords: $keywords";
I would call it as such :
$html = file_get_contents_curl("http://example.com/"); //<< I need to set the url with the user input without reloading the page
What you are looking for is called xhr, XMLHttpRequest or more commonly : AJAX.
Assuming you are using JQuery :
Client side :
<script>
function get_metas(){
url = $('#txt_url').val();
$('#result').load('your_script.php?url=' + encodeURIComponent(url));
}
</script>
<form id='search' method='post' onsubmit='get_metas();return false;'>
<input type='text' id='txt_url' name='url'/>
<input type='submit' value='OK'>
</form>
<div id='result'></div>
Server side :
...
$html = file_get_contents_curl($_GET['url']);
...
Be careful though as this can potentially turn your server into a proxy to do bad things.

Categories

Resources