I have built a website and I want to have an e-mail contact form on the web page, so that someone can send me a message.
I am using the code from this website: http://www.w3schools.com/php/php_secure_mail.asp
I am using the part that says PHP Stopping E-mail Injections
Even though my site gets very few hits per day (like less than 10 visitors) I am finding that I am getting 3 or 4 messages every day from "spammers" who just seem to be sending me random messages that are not related to the subject matter of the website.
I am fairly new to all this, so I would like to ask the question: Why is my PHP e-mail form attracting Spam and what can I do to stop it?
Ideally I would like to make it as easy as possible for the real users to contact me, and I would prefer it if I didn't have to use a CAPTCHA if possible.
Thanks so much
Code I am using:
<html>
<body>
<?php
function spamcheck($field)
{
//filter_var() sanitizes the e-mail
//address using FILTER_SANITIZE_EMAIL
$field=filter_var($field, FILTER_SANITIZE_EMAIL);
//filter_var() validates the e-mail
//address using FILTER_VALIDATE_EMAIL
if(filter_var($field, FILTER_VALIDATE_EMAIL))
{
return TRUE;
}
else
{
return FALSE;
}
}
if (isset($_REQUEST['email']))
{//if "email" is filled out, proceed
//check if the email address is invalid
$mailcheck = spamcheck($_REQUEST['email']);
if ($mailcheck==FALSE)
{
echo "Invalid input";
}
else
{//send email
$email = $_REQUEST['email'] ;
$subject = $_REQUEST['subject'] ;
$message = $_REQUEST['message'] ;
mail("someone#example.com", "Subject: $subject",
$message, "From: $email" );
echo "Thank you for using our mail form";
}
}
else
{//if "email" is not filled out, display the form
echo "<form method='post' action='mailform.php'>
Email: <input name='email' type='text'><br>
Subject: <input name='subject' type='text'><br>
Message:<br>
<textarea name='message' rows='15' cols='40'>
</textarea><br>
<input type='submit'>
</form>";
}
?>
There is a simple way to get rid of most spammers:
output an input field inside your form that as display: none; as a style. Ideally that is specified in an external css file.
Put that input field inside your form and give it an important name, like "name2" or something.
Then, when eveluating input, discard all requests that have avalue inside that field, as a real user can not see and and thus can't enter a value. Whereas spam bots most likely fill all fields they find on a page.
Related
So this is my first post, I try to tell what my issue's are.
I have bought a domain name that I want to sell.
So I code a simple HTML website with some CSS stuff.
OK. I also have a form in my HTML, that contains this:
<input type="text" placeholder="Amount" name="amount">
<input type="text" placeholder="Name" required name="name">
<input type="text" placeholder="Email Address" required name="email">
<div class="validation">
<button class="btn" name="submit">Send request</button>
$email_to = "email#email.com";
$amount = $_POST["amount"];
$name = $_POST["name"];
$email = $_POST["email"];
$email_subject = "Domeiname";
$headers = "From: " . $email . "\n";
$headers .= "Reply-To: " . $email . "\n";
ini_set("sendmail", $email);
$sent = mail($email_to, $email_subject, $amount, $headers, "-f" .$email);
if ($sent)
{
header("Location: https:mywebsite.com");
} else {
echo "There has been an error sending your comments. Please try later.";
}l
It's working and I receive emails. So my question is, is it safe? Is it vulnerable to hackers?
(I also receive in my Gmail, that this email can be spam/not from me).
Am I doing something wrong?
EDIT: Found another issue: In my email, I only receive the "amount" status and not the "name + email".
There are a number of libraries that will take all the hard work of securely sending email from you - such as swiftmailer.
<?php
require_once 'lib/swift_required.php';
// Sendmail
$transport = Swift_SendmailTransport::newInstance('/usr/sbin/sendmail -bs');
// Create the Mailer using your created Transport
$mailer = Swift_Mailer::newInstance($transport);
// Create a message
$message = Swift_Message::newInstance('Wonderful Subject')
->setFrom(array('john#doe.com' => 'John Doe'))
->setTo(array('receiver#domain.org', 'other#domain.org' => 'A name'))
->setBody('Here is the message itself')
;
// Send the message
$result = $mailer->send($message);
You may also find it very valuable to sign up for a service such as Mailgun and also setup your code to use their servers to actually send the email (there are libraries would setup as a 'transport' to send the message to them via HTTP, and then they email it to the final destination). There are a number of such 'ESP' (Email Service Providers), and many offer a substantial free-tier, so it won't cost you anything for even thousands of emails per month.
It looks as though you are sending an E-mail when a form is submitted. This is perfectly secure; there is no way a hacker could manipulate who the E-mail gets sent to; PHP is server-side code. Thus, $email_to = "email#email.com"; cannot get manipulated from the form itself, as it is hard-coded into your PHP.
Obviously, the $_POST data variables get passed through from the form, so their contents can be manipulated by the form -- though this is required in order for you to be able to retrieve the visitor's name and E-mail address.
PHPMailer did have a recent vulnerability in it, where an attacker could breach your website by entering a certain 'From' E-mail address, but this has since been patched. You still need to allow the user to enter their E-mail address, or you won't know who to reply to.
However, a user would still be able to create additional headers based on you not validating that the 'From' address is an actual valid E-mail address. You should validate this, and only send the E-mail if it is found to be valid:
if (!filter_var($email, FILTER_VALIDATE_EMAIL) === false) {
$sent = mail($email_to, $email_subject, $amount, $headers, "-f" .$email);
}
Note that you're also not actually doing anything with the $name variable. Assuming you're trying to make it display the person's name in the 'FROM' field in the E-mail, you need to pass it as:
$headers = "From: " . $name . " <" . $email . ">\n";
So that it gets rendered as From: Person <email#email.com>.
Hope this helps! :)
This question already has answers here:
PHP mail function doesn't complete sending of e-mail
(31 answers)
Closed 7 years ago.
So have a single form which only gets the email of the person and sends it to the email address I assigned. But I guess I wrote the code in a wrong way since I am getting errors. I have seen other stackoverflow problems but I am not sure why this isnt working.
This is the form in html.
<form style="margin-bottom:50px;" name="contactform" action="contact-form-handler.php" class="news-letter "method="post">
<div class="subscribe-hide">
<input type="text" name="email" class="form-control" placeholder="Email Address" >
<button type="submit" class="btn"><i class="fa fa-envelope"></i></button>
</div><!-- /.subscribe-hide -->
</form><!-- /.news-letter -->
and here is the PHP code in a different file.
<?php
$errors = '';
$myemail = 'masnadhossain#live.com';
empty($_POST['email']))
{
$errors .= "\n Error: all fields are required";
}
$email_address = $_POST['email'];
if (!preg_match(
"/^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/i",
$email_address))
{
$errors .= "\n Error: Invalid email address";
}
if( empty($errors))
{
$to = $myemail;
$email_subject = "Contact form submission";
$email_body = "You have received a new message. ".
" Here are the details:".
"Email: $email_address\n ";
$headers = "From: $myemail\n";
$headers .= "Reply-To: $email_address";
mail($to,$email_subject,$email_body,$headers);
//redirect to the 'thank you' page
header('Location: contact-form-thank-you.html');
}
?>
The error I get is server error 500
Your code have syntax error pleas check it.
Line no 3 should be:
if (empty($_POST['email']))
{
$errors .= "\n Error: all fields are required";
}
1.) The first problem you have is that you are sending the email address from a form input via post but you did not utilize it.
2.) To and From variables are having the same email address masnadhossain#live.com which is creating conflicts
3.) The Preg_Match for checking Email address validity is errorneous. I have re-written your code below.
If you are posting the users email(eg gmail,yahoomail etc) from a form input, this code will get you going.
In case you want to intialize the email within the code just change
$email_address = strip_tags($_POST['email']);
to may be
$email_address = 'user1#gmail.com';
Finally, the From variable must be the email address pointing to your website address. in this case I think it is masnadhossain#live.com
This code is working. please mark it as correct answer if it solve your problem....
<?php
//Users email address coming from form input eg. gmail,yahoomail etc.
$email_address = strip_tags($_POST['email']);
//validate the email address
$email_val= filter_var($email_address, FILTER_VALIDATE_EMAIL);
if (!$email_val){
echo "<font color=red><b>Invalid Email Address</b></font>";
exit();
}
$to=$email_val;
$subject = "Contact form submission";
$message = "Here is the message;
// set the from variable to any email pointing to your website
$from = "masnadhossain#live.com";
$headers = "From:" . $from;
$sent=mail($to,$subject,$message,$headers);
if($sent) {
print "<br><font color=green><b>Your mail was sent Successfully</b></font>";
//redirect to the 'thank you' page
header('Location: contact-form-thank-you.html');
} else {
print "<br><font color=orange><b>We encountered an error sending your mail.</b></font>";
}
?>
With an HTML contact form such as
HTML contact form
<h1>Contact Form</h1>
<p>Please fill in the following details and click on SEND.</p>
<form action="mail_contact.php" method="POST">
<p>Name<br> <input type="text" name="name"></p>
<p>Email Address<br> <input type="email" name="email"></p>
<p>Message<br><textarea name="message" rows="6" cols="50"></textarea><br>
<input type="submit" value="Send"><input type="reset" value="Clear"></p>
</form>
I am trying to stop spam messages getting through by checking for certain words being used in the message.
I have a .txt file which has words I want to filter for such as
File: spamwords.txt
CAN-SPAM
SEO
keywords
Keywords
In the PHP coding I have
mail_contact.php
<?php
// Create Variables
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
// Function to deal with errors
function died($error) {
echo 'We are very sorry, but there were error(s) found with the form you submitted.';
echo 'These errors appear below.<br><br>';
echo $error.'<br>';
echo 'Please press <b>back</b> and fix these errors.';
die();
}
// Validate email address
$error_message = "";
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error_message .= 'The email address you entered does not appear to be valid.<br>';
}
if(strlen($error_message) > 0) {
died($error_message);
}
// Prevent spammers from using contact form
//Create an array containing the words in the message
$MessageArray = explode(" ", $message);
//Get SPAM words from file and store them in an array
$SpamWords = file_get_contents('/spamwords.txt');
$SpamArray = explode("\r\n", $SpamWords);
//Cycle through all the words in the message
foreach($MessageArray as $word){
//Check the word for SPAM words, if it is don't send the email
if(in_array($word, $SpamArray)){
echo '<h1>Spam Guard</h1>';
echo '<p>Here in European Community, the Privacy and Electronic Communications Regulations 2003 cover the sending of email marketing. This legislation says that organisations must only send marketing emails to anyone if they have agreed to receive them, except where there is a clearly defined customer relationship.</p>';
echo '<p>It appears that you are attempting to send an unsolicited message (e.g. a marketing message).</p>';
echo '<p>We as an organisation do not send unsolicited messages and we request that you do the same for us.</p>';
echo '<p>If you are not attempting to send an unsolicited message, there may be an error in the system so please accept our apologies.</p>';
die();
}
}
//If we've made it to this point, our message doesn't contain any obvious SPAM words
// Formulate Email
$formcontent='Message: \n $message \n \n From: $name $email';
$recipient = << my email address >>;
$subject = 'Contact Form Message';
$mailheader = 'From: $name <$email> \r\n';
mail($recipient, $subject, $formcontent, $mailheader) or die('Error!');
echo 'Thank you for contacting us. We will be in touch with you very soon via your email address<br>' . $email;
?>
When I test this out with a message containing the word SEO for example SEO test message it should display the Spam Guard message to the visitor - hence the echo commands - and then not send the email to me, but it displays the thank you message and sends me the email.
Can anyone see where I have gone wrong as it has stumped me
[Additional Note]
I have been using a CAPTCHA mechanism but some still get through
Your explode function needs double quotes around its delimiter:
$SpamArray = explode("\r\n", $SpamWords);
With single quotes, explode will attempt to split on the \r\n literal.
Or you could use file() instead of filter_get_contents() which will return the file as an array, with each line per key. trim() each line that's returned and you have your resulting array:
$SpamArray = array_map("trim", file('/spamwords.txt'));
Eureka!!!
I had to take the forward slash out of $SpamWords = file_get_contents('/spamwords.txt');
mail_contact.php [Edited]
<?php
// Create Variables
$name = $_POST['name'];
$email = $_POST['email'];
$message = $_POST['message'];
// Function to deal with errors
function died($error) {
echo 'We are very sorry, but there were error(s) found with the form you submitted.';
echo 'These errors appear below.<br><br>';
echo $error.'<br>';
echo 'Please press <b>back</b> and fix these errors.';
die();
}
// Validate email address
$error_message = "";
if(!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$error_message .= 'The email address you entered does not appear to be valid.<br>';
}
if(strlen($error_message) > 0) {
died($error_message);
}
// Prevent spammers from using contact form
//Create an array containing the words in the message
$MessageArray = explode(" ", $message);
//Get SPAM words from file and store them in an array
$SpamWords = file_get_contents('spamwords.txt');
$SpamArray = explode("\r\n", $SpamWords);
//Cycle through all the words in the message
foreach($MessageArray as $word){
//Check the word for SPAM words, if it is don't send the email
if(in_array($word, $SpamArray)){
echo '<h1>Spam Guard</h1>';
echo '<p>Here in European Community, the Privacy and Electronic Communications Regulations 2003 cover the sending of email marketing. This legislation says that organisations must only send marketing emails to anyone if they have agreed to receive them, except where there is a clearly defined customer relationship.</p>';
echo '<p>It appears that you are attempting to send an unsolicited message (e.g. a marketing message).</p>';
echo '<p>We as an organisation do not send unsolicited messages and we request that you do the same for us.</p>';
echo '<p>If you are not attempting to send an unsolicited message, there may be an error in the system so please accept our apologies.</p>';
die();
}
}
//If we've made it to this point, our message doesn't contain any obvious SPAM words
// Formulate Email
$formcontent='Message: \n $message \n \n From: $name $email';
$recipient = << my email address >>;
$subject = 'Contact Form Message';
$mailheader = 'From: $name <$email> \r\n';
mail($recipient, $subject, $formcontent, $mailheader) or die('Error!');
echo 'Thank you for contacting us. We will be in touch with you very soon via your email address<br>' . $email;
?>
Check this out, it will be useful
Spam Word Blocker PHP
You can generate random variable name and random value for hidden input and save in session. After form submitting you can check they in $_REQUEST var. Also you can use interval between form rendering and submitting. Don't try to check spam words just protect from bots and don't use simple captcha.
So I got this PHP code for a "Contact us" form online (I do not code PHP myself), but it contains my e-mail address in full. Does the following form make my e-mail safe from spammers?
contact.php file (real email has been replaced by MYEMAIL#COMPANY.COM):
<?php
// Contact Form
// Get posted data into local variables
$EmailFrom = Trim(stripslashes($_POST['EmailFrom']));
$EmailTo = "MYEMAIL#COMPANY.COM";
$Subject = "A User Has Contacted You";
$Name = Trim(stripslashes($_POST['Name']));
$Message = Trim(stripslashes($_POST['Message']));
// Validation
$validationOK=true;
if (Trim($EmailFrom)=="") $validationOK=false;
if (Trim($Name)=="") $validationOK=false;
if (Trim($Message)=="") $validationOK=false;
if (!$validationOK) {
print "<meta http-equiv=\"refresh\" content=\"0;URL=error.htm\">";
exit;
}
// Prepare email body text
$Body = "";
$Body .= "Name: ";
$Body .= $Name;
$Body .= "\n";
$Body .= "Message: ";
$Body .= $Message;
$Body .= "\n";
// Send E-Mail
$success = mail($EmailTo, $Subject, $Body, "From: <$EmailFrom>");
// Redirect to Success page
if ($success){
print "<meta http-equiv=\"refresh\" content=\"0;URL=success.htm\">";
}
else{
print "<meta http-equiv=\"refresh\" content=\"0;URL=error.htm\">";
}
?>
html snippet:
<form method="POST" action="contact.php">
...
</form>
I've read that e-mail addresses contained in PHP is completely safe from crawlers since it is all server side (that is assuming your server/site is secure). Not sure if this is true or not, there's so much information out there I couldn't find a definitive answer after searching online. If someone could confirm if this code is safe to use or not that would be great, thanks!
Unless they have access to that file and read it, you're fine. They can't get at it. It's all server side like you said.
The address is safe, except in the unlikely event that the files gets served as plain text and is readable (as Sean says), but you should read up on email injection attacks as you're vulnerable to those.
Your e-mail is protected since it's all serverside, unless for example he has fpt access to your website or you have some type of vulnerability.
Also you might want to consider something like this to prevent flooding.
session_start()
define('TIME_INTERVAL', 120);
if(isset($_SESSION['ip']) && (time() - $_SESSION['last_post']) < TIME_INTERVAL)
}
die('stop spamming !');
{
$_SESSION['last_post'] = time();
$_SESSION['ip'] = $_SERVER['REMOTE_ADDR'];
Also regarding your e-mail validation you might wanna take a look at this, which also validates the domain of the email to see if it's an existing email server.
function validate_mail($email)
{
if (filter_var($email, FILTER_VALIDATE_EMAIL))
{
list($username,$domain)=split('#',$email);
if(checkdnsrr($domain,'MX'))
{
return true;
}
}
return false;
}
Simple answer, You are safe. Because the PHP elements will only be processed on the server, therefore there is no way for anyone to see your email address.
I'm using a PHP form to forward data to an email address. Everything seems to work fine except the the error message ["You have not entered an email"] appears when the page is loaded, before any input from the user is entered, rather than through validation when submitted.
The form is here http://www.soulwatt.com/contact.php
Note: I found this PHP code online after doing a search on how to forward data to email, so it is not mine. Please excuse the lack of proper code formatting.
<?php
$to = $_REQUEST['sendto'] ;
$from = $_REQUEST['Email'] ;
$name = $_REQUEST['Name'] ;
$headers = "From: $from";
$subject = "soulwatt.com Contact Data!!";
$fields = array();
$fields{"Name"} = "Name";
$fields{"Company"} = "Company";
$fields{"Email"} = "Email";
$fields{"Phone"} = "Phone";
$fields{"list"} = "Mailing List";
$fields{"Comments"} = "Comments";
$body = "Soul Watt has received the following information:\n\n";
foreach($fields as $a => $b) {
$body .= sprintf("%20s: %s\n",$b,$_REQUEST[$a]);
}
$headers2 = "From: noreply#soulwatt.com";
$subject2 = "Thank you for contacting Soul Watt!";
$autoreply = "Thank you for contacting us. Somebody will get back to you as soon as possible, usualy within 48 hours. If you have any more questions, please consult our website at www.soulwatt.com";
if($from == '') {
print "You have not entered an email. Please enter your email and try again.";
}
else {
if($name == '') {
print "You have not entered a name.<br />Please enter your name and try again.";
}
else {
$send = mail($to, $subject, $body, $headers);
$send2 = mail($from, $subject2, $autoreply, $headers2);
if($send) {
print "<p><span>THANK YOU FOR CONTACTING US!</span></p>";
print "<p><span>Someone will get back to you as soon as possible, usually within 48 hours. If you need immediate assistance regarding booking Soul Watt, please call Randy at (828) 729-3199.</span></p>";
}
else {
print "<p><span>We encountered an error sending your mail, please notify webmaster#soulwatt.com</span></p>";
}
}
}?>
Thanks for your help!
These 2 lines:
$from = $_REQUEST['Email'] ;
if($from == '') {
print "You have not entered an email. Please enter your email and try again.";
}
Mean that you check the email request (POST and GET) key. The first time you load this page this WILL be empty. You could add a check if there was a POST at all, for instance if there was submitted.
To be honest, there might a lot of problems with your code: a user can add all sorts of stuff in there, probably even add stuff in the headers to add 'to' fields and all.. You might be making a spam-machine here. This part: $headers = "From: $from"; just adds the request field FROM in your headers....
You'd want to wrap your validation section in
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
... do validation here ...
}
... print form here ...
That will only run the validation code AFTER you submit the form. As it stands now, it's running each time the page is loaded, so of course there's no form data to validate the first time around.
Does your form fields have the same name that you're checking?
I mean for
$from = $_REQUEST['Email'];
You should have
<input type='text' name='Email' /> <!-- Note the Capital E -->
I add my comments here:
Use $_POST or $_GET. Avoid $_REQUEST. That way you've more controll over your app.
Also, don't check emptiness with =="" try empty($from)
OK So if the form is on http://www.soulwatt.com/contact.php and you have
<form method="post" action="contact.php" name="contact_form" id="contact_form">
action="contact.php" : That means it is proccessing the form on the same address so you will see the results of the form processing on the same page, and since the form is empty, and you're checking it regardless of it having been posted or not, you get that error