PDA

View Full Version : web form problem



angyl
04-25-2006, 06:24 PM
I have a comment form on my site. I thought the code was fairly secure but I keep getting spam comments. Is there anything I can do to prevent that?


if (isset($_POST['submit_comment'])) {

if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['comment'])) {
die("You have forgotten to fill in one of the required fields! Please make sure you submit a name, e-mail address and comment.");
}

$entry = htmlspecialchars(strip_tags($_POST['entry']));
$timestamp = htmlspecialchars(strip_tags($_POST['timestamp']));
$name = htmlspecialchars(strip_tags($_POST['name']));
$email = htmlspecialchars(strip_tags($_POST['email']));
$url = htmlspecialchars(strip_tags($_POST['url']));
$comment = htmlspecialchars(strip_tags($_POST['comment']));
$comment = nl2br($comment);

if (!eregi("^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $email)) {
die("The e-mail address you submitted does not appear to be valid. Please go back and correct it.");
}

$result = mysql_query("INSERT INTO table (entry, timestamp, name, email, url, comment) VALUES ('$entry','$timestamp','$name','$email','$url','$comment')");

header("Location: comment.php?id=" . $entry);
}
else {
die("Error: you cannot access this page directly.");
}

atanamir
04-25-2006, 07:11 PM
One way to prevent this is to create a session variable with a random number for the ID of the form, e.g.


session_start();
$_SESSION['formid'] = mt_rand();

then to pass that along as a hidden variable in your form:


echo '<input type="hidden" name="form_id" value="' . $_SESSION['formid'] . '>';

When you validate the form, check if
$_POST['form_id'] == $_SESSION['formid']. If they're equal, then
unset($_SESSION['formid']). That should prevent both multiple posting and spam posts.

angyl
04-25-2006, 08:41 PM
Thanks for the suggestion.

I tried creating the random id and I got this error:


Warning: session_start(): Cannot send session cache limiter - headers already sent (output started at /home/blah/public_html/head.php:3) in /home/blah/public_html/comment.php on line 64

atanamir
04-25-2006, 09:36 PM
When you do session_start, you can't have any output before it. No HTML, no echoes, no ntohing. So it's best if you do session_start() as the first line in the PHP file.

angyl
04-25-2006, 09:46 PM
excellent! thank you.

angyl
05-05-2006, 10:18 PM
I don't know if I've implemented everything correctly - I'm still getting spam comments...
This is the form:


<?
session_start();
$_SESSION['formid'] = mt_rand();

<form method="post" action="process.php">
<input type="hidden" name="id" value="<? echo $id ?>">
<input type="hidden" name="timestamp" value="<? echo $timestamp ?>">
<input type="hidden" name="form_id" value="<? $_SESSION['formid'] ?>">
<table>
<tr><td width="45">name:</td><td width="164"><input type="text" name="name" size="25"></td></tr>
<tr><td width="45">email:</td><td width="164"><input type="text" name="email" size="25"></td></tr>
<tr><td width="45">comment:</td><td width="164"><textarea cols="25" rows="5" name="comment"></textarea></td></tr>
<tr><td colspan="2"><input type="submit" name="submit_comment" value="comment"></td></tr>
</table>
</form>


This is the process script:


<?
if (isset($_POST['submit_comment'])) {

if ($_POST['form_id'] == $_SESSION['formid']){
unset($_SESSION['formid']);
}

if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['comment'])) {
die("You have forgotten to fill in one of the required fields!");
}

$id = htmlspecialchars(strip_tags($_POST['id']));
$timestamp = htmlspecialchars(strip_tags($_POST['timestamp']));
$name = htmlspecialchars(strip_tags($_POST['name']));
$email = htmlspecialchars(strip_tags($_POST['email']));
$comment = htmlspecialchars(strip_tags($_POST['comment']));
$comment = nl2br($comment);

if (!eregi("^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $email)) {
die("The e-mail address you submitted does not appear to be valid.");
}

$result = mysql_query("INSERT INTO table (id, timestamp, name, email, comment) VALUES ('$id','$timestamp','$name','$email','$comment')");

header("Location: entry.php?id=" . $id);
}

else {
die("Error: you cannot access this page directly.");
}
?>


Am I missing something?

lansing
05-06-2006, 09:41 PM
I don't know if I've implemented everything correctly - I'm still getting spam comments...
This is the form:


<?
session_start();
$_SESSION['formid'] = mt_rand();

<form method="post" action="process.php">
<input type="hidden" name="id" value="<? echo $id ?>">
<input type="hidden" name="timestamp" value="<? echo $timestamp ?>">
<input type="hidden" name="form_id" value="<? $_SESSION['formid'] ?>">
<table>
<tr><td width="45">name:</td><td width="164"><input type="text" name="name" size="25"></td></tr>
<tr><td width="45">email:</td><td width="164"><input type="text" name="email" size="25"></td></tr>
<tr><td width="45">comment:</td><td width="164"><textarea cols="25" rows="5" name="comment"></textarea></td></tr>
<tr><td colspan="2"><input type="submit" name="submit_comment" value="comment"></td></tr>
</table>
</form>
In this you didn't close your PHP tag after setting the session. Try that & see if that helps.



This is the process script:


<?
if (isset($_POST['submit_comment'])) {

if ($_POST['form_id'] == $_SESSION['formid']){
unset($_SESSION['formid']);
}

if (empty($_POST['name']) || empty($_POST['email']) || empty($_POST['comment'])) {
die("You have forgotten to fill in one of the required fields!");
}

$id = htmlspecialchars(strip_tags($_POST['id']));
$timestamp = htmlspecialchars(strip_tags($_POST['timestamp']));
$name = htmlspecialchars(strip_tags($_POST['name']));
$email = htmlspecialchars(strip_tags($_POST['email']));
$comment = htmlspecialchars(strip_tags($_POST['comment']));
$comment = nl2br($comment);

if (!eregi("^([_a-z0-9-]+)(\.[_a-z0-9-]+)*@([a-z0-9-]+)(\.[a-z0-9-]+)*(\.[a-z]{2,4})$", $email)) {
die("The e-mail address you submitted does not appear to be valid.");
}

$result = mysql_query("INSERT INTO table (id, timestamp, name, email, comment) VALUES ('$id','$timestamp','$name','$email','$comment')");

header("Location: entry.php?id=" . $id);
}

else {
die("Error: you cannot access this page directly.");
}
?>


Am I missing something?The processing page looks ok...

angyl
05-08-2006, 05:10 PM
Thank for catching not closing the php.

On the actual page it is closed - I just missed it when I cut out the filler content between the head of the page and the entry form at the bottom.

Any other suggestions?