Reputation: 1
I have not been able to successfully submit a form I am working on in Chrome or Firefox. The form works in Safari, however.
I just started trying to use PHP last week and modified code from this post on CSS Tricks. I am trying to give the session a random token, store that token in a variable, set that token to a hidden input field, and then make sure the two match when the form is submitted.
The problem is that the session token that is created doesn't match the token assigned as a value to the hidden input. When the form is submitted, a new session token is recreated and thus doesn't match the original random number from the session. The curious thing is that it works in Safari and not other browsers.
The PHP
<?php
session_start();
function generateFormToken($form) {
// generate a token from an unique value, took from microtime, you can also use salt-values, other crypting methods...
$token = md5(uniqid(microtime(), true));
// Write the generated token to the session variable to check it against the hidden field when the form is sent
$_SESSION[$form.'_token'] = $token;
echo $token;
return $token;
}
function verifyFormToken($form) {
// check if a session is started and a token is transmitted, if not return an error
if(!isset($_SESSION[$form.'_token'])) {
return false;
}
// check if the form is sent with token in it
if(!isset($_POST['token'])) {
return false;
}
// compare the tokens against each other if they are still the same
if ($_SESSION[$form.'_token'] !== $_POST['token']) {
return false;
}
return true;
}
function check_input($data)
{
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;
}
if (verifyFormToken('form1')) {
$name = check_input($_POST["name"]);
$email = check_input($_POST["emailaddress"]);
$message = check_input($_POST["message"]);
$ForwardTo = '[email protected]';
$details='Name: '.$name."\n".'Email: '.$email."\n".'Message: '.$message."\n";
//do stuff
mail($ForwardTo,"Construction of Hope Contact",$details,"From:$email");
}
?>
The related form:
<!--Markup for Contact form-->
<form action='index.php' method='post' class='contact-format'>
<p><input type="hidden" name="token" value="<?php echo $newToken; ?>"></p>
<p>
<button type="submit" name='submit' class="btn btn-primary button">Send</button>
</p>
Upvotes: 0
Views: 15003
Reputation: 1
The functionality of my code seemed fine in Safari, but other browsers mismatched the token.
The issue involved .... not having a favicon.
This post was the key in solving the problem.
Upvotes: 0
Reputation: 12505
I think what you have is pretty close. I think I would change a couple of things, but overall I think what you have is close:
/functions/validate.php
function fetchToken($form)
{
$token = md5(uniqid(microtime(), true));
$_SESSION['token'][$form] = $token;
// Just return it, don't echo and return
return $token;
}
function matchToken($form)
{
if(!isset($_POST['token'][$form]))
return false;
// I would clear the token after matched
if($_POST['token'][$form] === $_SESSION['token'][$form]) {
$_SESSION['token'][$form] = NULL;
return true;
}
// I would return false by default, not true
return false;
}
index.php
// Include functions
include(__DIR__.'/functions/validate.php');
// Start session
session_start();
// match the token
if(matchToken('mailer')) {
// do stuff
echo true;
}
?>
<form action='index.php' method='post' class='contact-format'>
<!-- You will echo here and also set the session variable here -->
<!-- I would also use an array to contain my tokens, cleaner I think -->
<input type="hidden" name="token[mailer]" value="<?php echo fetchToken('mailer'); ?>">
<button type="submit" name='submit' class="btn btn-primary button">Send</button>
</form>
Upvotes: 1