Forum Moderators: coopster
I have a spammer or some person clicking on my contact form 100's of times a day.
The Form action sends the form data to another page and the PHP mail()function sends me the form details in an email.
----
contact.php
<form name="Contact_Form" method="post" action="../contact_mail.php">
contact_mail.php
mail($to,$subject,$message,$headers);
-----
All the spammer has to do is click the browsers back button to submit the same data over and over.
Any ideas about how I can prevent this attack?
// dont send another message
}
else {
$expire = time()+60*60*2; // two minute cookie
setcookie("name",$_POST['name'],$expire,"/");setcookie("email",$_POST['email'],$expire,"/");
setcookie("url",$_POST['url'],$expire,"/");
mail(...)
}
This would work, I think, however it's quite easy to turn cookies off these days.
Why not store the message and details in a DB, and do a check against the message and authorname and e-mail address. If they are the same, give the person a polite GTFOH message, if not, accept the message?
The simplest solution (IMO) - is to create a blacklist of words. Should one of these words be in the message or title, don't bother sending - but report back to the spammer with 'delivered message'
$spam = false;
$blacklist = array('viagra','porn','seo');foreach ($blacklist as $word) {
if (strpos(strtolower($message), strtolower($word)) {
// this is spam
$spam = true;
break;
}
}if (!$spam) {
mail($to,$subject,$message,$headers);
}print 'Thank you for your spam - erm - message.';
Lots of enhancements you could add, putting the blacklist in a file. Counting the occurances to provide a tolerance, logging the spam so that you do have a record somewhere....
My blacklist generally contains a few very obvious spam terms plus some specific domain names, it also runs on comments, guestbooks, and messages on a community website I run, very effectively.
Another bit of advice to newbies: never let the e-mail address 'to' be sent by the script if you are just sending this to yourself or a few email addresses that remain the same. Hard-code these. For 'mail a friend' scripts, make sure your links have weird names that don't sound at all like 'mail' or 'friend'. Or the bots will find you and use these for spam. Haven't seen this happening yet myself, but spammers are sending such weird crud these days why wouldn't they stoop to 'mail a friend' forms, as long as they can squeeze some viagara message in?
just off the top of my head, if I sent the data to a database would I use a SELECT statement and an IF statement somewhat like this:
SELECT * FROM contact_table WHERE email = $email AND name = $name
if ($name ==
** My only concern for this is when legitimate people use my contact form to contact me multiple times.
gethan,
Blacklisting is not my problem. The spammer is hitting the back button and submitting the same form data over and over.
I need a solution to prevent spammers from submitting the same form data over and over.
musicales
I think it is part of several new waves of spamming. I have contact forms and guestbooks on multiple websites I manage for other people and we have recently been getting a lot of spam. Some asking for immediate contact, some to advetise products, and some to post random links. All anonymous and it seems impossible to block it.
I don't think there is a full proof way to stop contact form attacks but it would be nice to make it as hard as possible to attack them....
Database sounds like the mst promising solution so far.
What if when the form data (contact.php) is sent to the form handler (contact_mail.php) and the page automatically closes but opens up a new window?
This way the spam attacker cannot hit the back space.
I read that we can use onLoad=Window Close() (for contacy_mail.php) in php but I have not been able to track down a way to script it correctly. Plus it would need to automatically pop-up a new window to prevent back button.
Any ideas on how to implement this? Or am I talking craziness?
If you tell them they have been blocked, they will continue to find a work around and you will have to step up security again. If they don't know, they will eventually give up - they'll probably get bored.
One thing I would do is to email the response, but also store the message body in a database. Get the script to not send duplicate messages within a specified time limit.
A couple of other things that can be done: Generate a hidden field with a unique number on the form. Duplication of this form submission would mean the unique number would be the same - dissallow this.
Alternatively, and possibly simpler, would be to set the expiry date of the page to the current time and date. Hitting the back button would make most browsers refresh the page from your server rather than from their cache. This means that the back button would reload the form (and hence the fields would be blank).
However, you don't know if this person is hitting the back button or if he/she is clicking on a favorites item repeatedly.
If the message is identical every time, you could make things even more difficult by creating a new folder in your email client and create rules to move messages into an unimportant folder where you can filter out genuine enquiries from real enquiries.
I find that they get the idea they are speaking to a robot when the have to fill in a form box, contact made via normal email seems much more helpful from both perspectives.
Use a simple email link with this script to obfuscate the addy:
<script language="JavaScript">
<!--
var name = "yourname";
var domain = "yourwebsite.com";
document.write('<a href=\"mailto:' + name + '@' + domain + '\">');
document.write(name + '@' + domain + '</a>');
// -->
</script>
blacklisting spam words is one option to reduce spam generally. Your spammer must be trying to advertise something - with a spam word - block it you will not recieve any of the spam. Thus it is a good solution - don't be so dismissive.
Setting cookies, putting the messages in a database and filtering duplicates - are other good solutions. Using combinations of these can stop even the most determined spammer.
Please also be aware that although you may have started the topic - offering general advice and ideas that help all contributors and future readers should be the goal.
My vote opens in a popup, checks if a user already voted for the item in question, if not user may cast vote, on clicking a radio button the form is submitted, the vote is processed, next in a separate table I store what the user voted on and the rating he/ she gave it. When the popup loads again, or he/ she presses F5 or back, the entire procedure starts over again and they'll receive an error message. Ofcourse, as suggested, you may chose not to display such an error message
in my opinion this is the best way, because you can also use the extra data in the seperate table for other purposes
Plus, a huge added benefit, you wont need javascript to do it either...which can be turned of also, limiting your target audience :)
ofcourse you need javascript in my example, but that was just an example :)
if it's one person getting on your nerves (or you think it is), disable the form and give people other ways of contacting you. i would do this for some hours only and would switch back then but with changing the url (old page still there, so the bad guy does not see the changes immediatly.
this can be done quite fast and you can additionally check the intention of the bad guy (robot or person etc.).
if many people are spamming your form (don't know for what that form is intended to), think about why they might want to do it and then think about technical solutions. often a non technical solution does work much better then technical ones.
if they even can use your form as their mailer, disable the form immediatly and secure it. this _can_ be the cause for them to use your form.
Creating database and using a time based if statement is sort of the train of thought I was following. I checked out a whole bunch of websites with solutions but none worked because of the back button issue.
I am going to test implement that theory this weekend.
Can someone help me workshop the SELECT and IF STATEMENT:
"SELECT * FROM contact_table WHERE insert_timestamp = $insert_timestamp";
if ($submit) {
if ($insert_timestamp <= How do i make time is =< 10 minutes?) {
echo ("message here")
} else {
$sql = "INSERT INTO contact_table (insert_timestamp, name, email, comments) VALUES ('$insert_timestamp','$name','$email','$comments')";
$result = mysql_query($sql);
}
}
Code by Lederer Olaf
Do you have enough from submitting the same form multiple times to your database and/or mail? Then this should be your solution. With this function (and also session support) is it possible prevent the user to post a form twice (or more) while using server side form field validation. The script checks the unique string from the current submission against the post before and stops if the string is the same.
<?php
function prevent_multi_submit($type = "post") { // use "get" if this is your form method
session_start();
$string = "";
$posted_array = ($type == "get")? $_GET : $_POST;
foreach ($posted_array as $val) {
$string .= $val;
}
if (isset($_SESSION['last'])) {
if ($_SESSION['last'] === md5($string)) {
return false;
} else {
$_SESSION['last'] = md5($string);
return true;
}
} else {
$_SESSION['last'] = md5($string);
return true;
}
}
/* example of use:
if (isset($_POST)) {
if ($_POST['field']!= "" && strlen < 25) { // place here the form validation and other controls
if (prevent_multi_submit()) { // use the function before you call the database
mysql_query("INSERT INTO tabel..."); // or send a mail like...
mail($mailto, $sub, $body);
} else {
echo "The form is already processed";
}
} else {
// your error about invalid fiels
}
} */
?>
Ofcourse, you may want to supress the display of an error message like was suggested further up in this thread
I have been trying to work with the code above from the link you originally provided. It isn't totally clear about which fields to use or how to customize it. I will keep trying.
I want to use a timestamp based statement because some legit people contact me multiple times and various times. I wouldn't want to block their messages.
just use one of your form fields to check if the form is being submitted and next call the function. It doesnt matter for your regular users who post frequently, because for them, if they use the forms like they should, a different string will be generated eacht time and the submit will work just fine
the aim:
- not bound to any cookies
- not bound to ip adresses
- failsafe
the idea:
creating a "session" for a form only prevents being kicked "back".
1.) each time a user submits data with your form, this process has got a unique id. this unique id is stored into the database with a timestamp. if the unique id exists in the database already, the crap is dropped (cauz that tweaky monkey submitted multiple times or used the back button)
2.) as you guess right now, the unique id is created before the form is submitted. so pressing the back button will not change the unique id.
3.) to ensure this is working and assuming your form script is called contact.php: once contact.php is requested and no uniqueid isset(), contact.php redirects to itself setting the uniqueid. ensure to tell the client that this redirect is PERMANENT, so pressing the back button will give "it" a good feeling about using the redirected version (with it's uniqueid) instead.
this should do the trick if we are talking about pressing the back button or submitting multiple times. this will not block out people using software explicitly created for your personal form. they will ever cheat you if you approach them this or the other ways discussed in here.