I want to use a php script to send emails from a html file on a website.
Would this php script be secure enough against hacking and spam?
<?php
$to = "emailto#site.com";
$subject = "Sent from site";
$email = $_POST['emailFrom'];
$message = $_POST['message'];
$email = filter_var($email , FILTER_SANITIZE_EMAIL);
$message = filter_var($message , FILTER_SANITIZE_EMAIL);
$message = $email . $message;
mail($to, $subject, $message, "From: webpage#site.com");
?>
FILTER_SANITIZE_EMAIL removes illegal email address characters from a string; this is, therefore not the best option for the contents of an email (however useful it may be for email addresses). Whilst removing HTML special characters is useful when preventing XSS attacks, it is worth noting that there are legitimate reasons to post < and > in messages (i.e. right now). Therefore it is better to convert these characters to their html entities.
I.e.
< would become <
and > would become >
So in order to change html characters to their entities replace:
$message = filter_var($message , FILTER_SANITIZE_EMAIL); with
$message = htmlspecialchars($message);
Other than that it looks good; but remember, in cases where a database is involved database sanitisation should also be added.
Related
This question already has answers here:
UTF-8 all the way through
(13 answers)
Closed 1 year ago.
I am getting some data from a html form and sending them by email with PHP.
The issue is that i am getting weird characters because the language that the user writes in the form is Czech.
For example the name Anežka becomes Anežka
This is the code i have for my php which being used for sending the email.
<?php
if(isset($_POST['submit'])){
$to_alex = "myemail#honeywell.com"; // this is your Email address
$first_name = $_POST['fname'];
$first_name=mb_convert_encoding($first_name, "UTF-8", "ISO-8859-1");
$last_name = $_POST['lname'];
$email = $_POST['email'];
$skola = $_POST['vysoka_skola'];
$obor = $_POST['obor'];
$prace = $_POST['prace'];
$phone_num=$_POST['phone_number'];
$linkedin=$_POST['linkedin'];
$oponenta=$_POST['oponenta'];
$vedouciho=$_POST['vedouciho'];
$files = $_FILES['myfile']['name'];
$kategorie = $_POST['kategorie'];
//echo gettype($files);
$all_thesis_string="";
$all_vedouciho_string="";
for($index=0;$index<count($_FILES['myfile']['name']);$index++){
$all_thesis_string.=$_FILES['myfile']['name'][$index].","; //create a string with all bachelor attachments of user
}
for($index=0;$index<count($_FILES['vedouciho_files']['name']);$index++){
$all_vedouciho_string.=$_FILES['vedouciho_files']['name'][$index].","; //create a string with all vedouciho attachments of user
}
for($index=0;$index<count($_FILES['oponenta_files']['name']);$index++){
$all_vedouciho_string.=$_FILES['oponenta_files']['name'][$index].","; //create a string with all oponenta attachments of user
}
$subject = "Form submission of ".$first_name." ".$last_name;
$message = "User Details: \n\n Jméno: $first_name \n Příjmení: $last_name \n Email: $email \n Telefon: $phone_num \n Linkedin: $linkedin \n Vysoká škola: $skola \n Studijní obor: $obor \n Odkaz na bakalářskou práci: $prace \n Kategorie: $kategorie \n Posudek oponenta: \n $oponenta \n Posudek vedouciho: \n $vedouciho \n Bakalářská práce: $all_thesis_string \n Vedouciho files: $all_vedouciho_string";
$headers = "From:" . $first_name;
mail($to_alex,$subject,$message,$headers);
echo '<span style="color:#AFA;text-align:center;"><strong>"Přihláška úspěšně odeslána. Děkuji "</strong></span>';
//include 'upload.php';
// You can also use header('Location: thank_you.php'); to redirect to another page.
}
?>
I have tried mb_convert_encoding in my last attempt but still i have the issue.
You need to tackle possible issues on both input and output stages of your program:
make sure, the browser knows, that you want UTF-8: It needs the tag <meta charset="utf-8"> somewhere in the <head> of your HTML. Otherwise it is possible, that it falls back to some legacy encoding when sending form data back to you.
make sure, e-mail clients know, that you send UTF-8 to them. They, too, will fall back to legacy encodings without explicitly telling them. Try adding these headers to the mail:
Mime-Version: 1.0
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: quoted-printable
If you want UTF-8 in the subject and/or To fields, you need a separate way of quoting. I suggest you take a look at the excellent PHPMailer package that will handle all that for you.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I know this is a simple question, but having a hard time finding a simple solution.
I have a form on my PHP site that takes in the user message, then sends an email to my client with the message. I want the message sent to my client to be easily readable, without escaped characters \r , \n , \" , etc.
For example, the message is currently coming into the email as:
test\'s\r\nnew line \r\n\"quote\"
What I want it to come in as:
test's
new line
"quote"
Current code is:
if(isset($_POST['submit']) && !empty($_POST['email'])){
//Process form
$name = $_POST['name'];
$name = mysql_prep($name);
$email = $_POST['email'];
$email = mysql_prep($email);
$message = $_POST['message'];
$message = mysql_prep($message);
$emailto = "client_email1#gmail.com,client_email2#gmail.com";
$subject = "Message from '$name'";
// the message
$message = "<html><body>
<h3>Title</h3>
From: $name<br>
Email: $email<br><br>
Message:<br>
$message<br><br>
</body></html>";
//headers make the mail() work
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
mail($emailto, $subject, $message, $headers);
What you need is stripslashes() and nl2br().
nl2br will make newlines html br tags.
Stripslashes does what the name indicates, it removes slashes that is escape slashes.
echo stripslashes(nl2br($str));
Example: https://3v4l.org/RPYWt
Couple issues, first was my $message = mysql_prep($message); function was creating the escaped characters, so I just put that function after the mail() function. mysql_prep() was used to prevent mysql injection.
Second, I needed the $message = nl2br($message) function to maintain the user entered new lines from the form so the client can see the message as it was typed. I put the nl2br() function just after the $message = $_POST['message']; line.
I have a strange problem with my PHP contact form, every 15 minutes or so I get a blank email and receive them though the day?! When I fill out the form I get the details sent to me at once and all of the fields are filled out fine.
I use PHP for the form and the jQuery validate for the validation, the form works and so does the validation but since I am not strong with PHP maybe it's the process that's not right?
form.php - from: https://1stwebdesigner.com/php-contact-form-html/
<?php
$name = $_POST['name'];
$email = $_POST['email'];
$phone = $_POST['phone'];
$call = $_POST['call'];
$website = $_POST['website'];
$priority = $_POST['priority'];
$type = $_POST['type'];
$message = $_POST['message'];
$formcontent=" From: $name \n Phone: $phone \n Call Back: $call \n Website: $website \n Priority: $priority \n Type: $type \n Message: $message";
$recipient = "youremail#here.com";
$subject = "Contact Form";
$mailheader = "From: $email \r\n";
mail($recipient, $subject, $formcontent, $mailheader) or die("Error!");
echo "Thank You!";
?>
I had to take the form down as I receive so many mails a day. The $recipient was set to my email but left it as a dummy address for this post.
As per your code snippet. It's nothing to do with 15 mins blank email issue. Your form might been targeted with some bot or malicious script. However, it's really simple form. There are several standard practices for forms but for starters, you may be looking into following links to get the whole idea.
https://www.w3schools.com/php/php_form_complete.asp
https://www.w3schools.com/php/showphp.asp?filename=demo_form_validation_complete
When you are done with this reading, you should be looking into javascript Form Validation and Capcha integration. Once you are comfortable with Javascipt Validation, you migh jump to Jquery Validation or jQuery Validation plugins.
Above links are not really end of the world but you shall at least get the idea for basic form submission process.
Hope this helps.
A client recently got a spam warning from their host.
I think I have pin pointed the issue to an old contact us form. Simple html on the front end and a simple PHP script on the back end.
if ($_POST['submit'] == "Send"){
//START SEND MAIL SCRIPT
$mail = $_POST['email'];
$to = "me#gmail.com";
$subject = "Message from Website Contact Us Form";
$headers = "From: Contact us Form <webmaster#website.co.uk>";
$message = "Message from Contact Us Form\n\n";
$message .= "\nName: " . $_POST['contactname'];
$message .= "\nEmail: " . $_POST['contactemail'];
$message .= "\nTelephone: " . $_POST['contactphone'];
$message .= "\n\n\nMessage:\n" . $_POST['contactmessage'];
if(mail($to,$subject,$message,$headers)) {
header('Location: http://www.website.co.uk/contact-us/?action=success');
}else{
header('Location: http://www.webisite.co.uk/contact-us/?action=fail');
}//END IF MAIL
}//END SCRIPT
I know the remedies to fix it such as sanitizing post vars properly, using captchas, using a hidden 'honeypot' blank field, js tricks etc etc (I also like the look of this script too http://www.alt-php-faq.com/local/115/)
But to help me understand what was going on I want to know how this script is being manipulated. A foreign script posting vars to it but how do they send email to anyone apart from
'me#gmail.com' or if they are forcing cc / bcc fields somehow why do I not get all spam as well??
Thanks
Line like this $message .= "\nName: " . $_POST['contactname']; can be dangerous.
If $_POST['contactname']='MegaSteve4 \r\nCc: email1#mail.com, email2#mail.com'; are set, 2 uses will get spam mail.
See carefully. Its appending more headers. In this case Cc. I am not sure if Cc is a raw email header. But I hope you get the idea.
You're not doing any escaping of the post data. That means that this form is vulnerable to injection attacks.
I couldn't tell you how they did it, but that's probably what happened.
I have a simple PHP mailer script that takes values from a form submitted via POST and mails them to me:
<?php
$to = "me#example.com";
$name = $_POST['name'];
$message = $_POST['message'];
$email = $_POST['email'];
$body = "Person $name submitted a message: $message";
$subject = "A message has been submitted";
$headers = 'From: ' . $email;
mail($to, $subject, $body, $headers);
header("Location: http://example.com/thanks");
?>
How can I sanitize the input?
Sanitize the post variable with filter_var().
Example here. Like:
echo filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);
Since you're not building an SQL query or anything here, the only relevant validation that I can see for those inputs is an email validation for $_POST["email"], and maybe an alphanumeric filter on the other fields if you really want to limit the scope of what the message can contain.
To filter the email address, simply use filter_var:
$email = filter_var($email, FILTER_SANITIZE_EMAIL);
As per Frank Farmer's suggestion, you can also filter out newlines in the email subject:
$subject = str_replace(array("\r","\n"),array(" "," "),$subject);
As others have noted, filter_var is great. If it's not available, add this to your toolchest.
The $headers variable is particularly bad security-wise. It can be appended to and cause spoofed headers to be added. This post called Email Injection discusses it pretty well.
filter_var is great, but another way to assure that something is an email address and not something bad is to use an isMail() function. Here's one:
function isEmail($email) {
return preg_match('|^[_a-z0-9-]+(\.[_a-z0-9-]+)*#[a-z0-9-]+(\.[a-z0-9-]{2,})+$|i', $email);
};
So to use this, you could do:
if (isset($_POST['email']) && isEmail($_POST['email'])) {
$email = $_POST['email'] ;
} else {
// you could halt execution here, set $email to a default email address
// display an error, redirect, or some combination here,
}
In terms of manual validation, limiting the length using substr(), running strip_tags() and otherwise limiting what can be put in.
You need to remove any newlines from input provided by users in $headers, which gets passed to mail() ($email in your case)! See Email injection.
PHP should take care of sanitizing $to and $subject, but there are versions of PHP with bugs (Affected are PHP 4 <= 4.4.6 and PHP 5 <= 5.2.1, see MOPB-34-2007).
You can use the code from artlung's answer above to validate email..
I use this kind of code to prevent header injection ..
// define some mail() header's parts and commonly used spam code to filter using preg_match
$match = "/(from\:|to\:|bcc\:|cc\:|content\-type\:|mime\-version\:|subject\:|x\-mailer\:|reply\-to\:|\%0a|\%0b)/i";
// check if any field's value containing the one or more of the code above
if (preg_match($match, $name) || preg_match( $match, $message) || preg_match( $match, $email)) {
// I use ajax, so I call the string below and send it to js file to check whether the email is failed to send or not
echo "failed";
// If you are not using ajax, then you can redirect it with php header function i.e: header("Location: http://example.com/anypage/");
// stop the script before it reach or executing the mail function
die();
}
The mail()'s header filtering above is too strict, since some users may be using the filtered strings in their message without any intention to hijack your email form, so redirect it to a page that is explaining what kind of strings that is not allowed in the form or explain it on your form page.