- Edited
Hope the appearance of this post is okay. Din't see any means of specifying code blocks, so I surrounded them with BB tags.
I have a form that I decided to include Google recaptcha as an added measure of security.
My validation script includes a whitelist of form input elements, using the elements name attribute.
When I added the recaptcha it triggers a validation error, not a php error, because the recaptcha is not whitelisted.
I read that HTML5 does not allow assigning the name attribute to div. i.e. <div name="myName"></div>
Against convention, I tried adding a name to the recaptcha div and adding that name to the whitelist. That approach failed.
There is an iframe within the captcha div that has the name attribute. I tried using the iframe name in the whitelist. That approach also failed.
There is a hidden input within the captcha div that has an id="recaptcha-token". I added 'recaptcha-token' to the whitelist. This approach also failed.
The hidden input is generated by the recaptcha api, so I don't think I have a means of assigning a name attribute to this input.
If I am not able to to assign the name attribute. I assume that I must use some other means to include the recaptcha element in the $_POST
array,
but I don't know how to accomplish this.
I have also tried:
ob_start();
<p><div class="g-recaptcha" data-sitekey="<?php print $public_key;?>"</div></p>
$captcha_elem = ob_get_clean();
$_POST['myCaptcha'] = $captcha_elem;
array_push($whitelist, $_POST['myCaptcha']);
echo"<pre>";print_r($whitelist);echo"</pre>";
Does anyone have a workaround or suggestion ?
Note: form validation and whitelist all worked as expected prior to adding recaptcha.
This is the div within the form.
<div class="row">
<div class="col-md-12">
<div class="g-recaptcha" data-sitekey="<?php print $public_key;?>"></div>
</div>
</div>
There is a hidden input within the form that contains a token. This input & token are completely separate of the Google Recaptcha and not to be confused with the hidden input of the captcha api. However this token must be verified before the form inputs are compared to the $whitelist.
Here are the code blocks:
function verifyFormToken($form) {
// check if a session is started and a token is transmitted, if not return an error
if(!isset($_SESSION[$form.'_token'])) {
$errors[]= "Session not set and no token";
return false;
}else{
//echo 'Session token is set.'.'</br>';
}
// check if the form is sent with token in it
if(!isset($_POST['token'])) {
$errors[]= 'No form token was sent!'.'</br>';
return false;
}
// compare the tokens against each other see if they are still the same
if ($_SESSION[$form.'_token'] !== $_POST['token']) {
$errors[]= 'tokens don\'t match!'.'</br>';
return false;
die();
}else{
//echo 'Tokens match. Good to go.'.'</br>';
return true;
}
}
// VERIFY LEGITIMACY OF TOKEN
if (verifyFormToken('form1')) {
// Building a whitelist array with keys which will send through the form, no others would be accepted later on
$whitelist = array('token','req-fName','req-lName','req-email','req-phone','req-address','req-city','req-state','req-zip','req-message','req_method','req-dateDepart','req-dateReturn','submit');
// Building an array with the $_POST-superglobal
foreach ($_POST as $key=>$item) {
$bar = each($whitelist);
print_r($bar);
// Check if the value $key (fieldname from $_POST) can be found in the whitelisting array, if not, die with a short message to the hacker
if (!in_array($key, $whitelist)) {
writeLog('Unknown form fields');
die('Hack-Attempt detected. Only the fields originally included in the form are allowed!');
//echo "Hack-Attempt detected.";
}
}
}
(MOD: changed [ php ] tags to [ code=php ]...[ /code ] tags)
(MOD: changed [ html ] tags to [ code=html ]...[ /code ] tags except when inline)