I have a simple web page where I get some data from $_POST that users input: comments, usernames, etc. And I send them to email and save them on database. My problem is what when I send to email, doesn't matter what client is, I only see gibberish. I tried declaring the meta tag in the emails with all iso 88xx, utf8, windows, etc., but with no success. Also tried a million examples of htmlentities(), all leading to the same thing... plain gibberish. (Althought the source code shows different things sometimes, the plain text never changes).
Example code:
if (isset($_POST['name'])) {
$name = htmlentities($_POST['name'], ENT_QUOTES);
}
A result of mail() of $name (Don Quijóte) would be something like this "Don Quijóte".
Sorry if this is a repost but I just can't get this working.
Have you tried setting the headers, something like...
// Always set content-type when sending HTML email
$headers = "MIME-Version: 1.0" . "\r\n";
$headers .= "Content-type:plain/text;charset=UTF-8" . "\r\n";
mail($to,$subject,$message,$headers);
This sets the encoding to UTF-8. More here:
http://www.w3schools.com/php/func_mail_mail.asp
It is surprisingly hard to send a mail in the right way. The error you get with Don Quijote is due to the fact that your string is in utf8 but it is showed with ISO8859 encoding. (That is why you get that weird A and a small 3.
I would recomend using php mailer You can get it here
It is way simpler to setup and it will be more efficient if you at some time in the future need to send out a lot of emails. (Because mail() opens and closes the connection on each call)
Also be aware that if you are using utf-8 everything should be with utf-8. Your database should be set to utf-8. You outputs to html and so on. Every step of the way you should be sure it is utf8.
Related
I am feeling a bit awkward, because I am generating a mail-body with PHP without escaping the variables. In HTML I am using htmlspecialchars() or similar functions, for command lines escapeshellarg(), but for mails? For example something like this:
<?php
$usercontent = $_GET['usercontent'];
mail("dummy#nowhere.tld", "My Subject", "My body with $usercontent included");
?>
What could a possible attacker do with a script like the one above and how could I protect against such an attack? Or is PHP mail() save and why?
Update
Please refer to the example:
Only the body is affected (No Headers!)
Content-Type is text/plain
Some proof to the answer would be nice
MTA is a postfix sendmail with "/usr/sbin/sendmail -t -i"
The basic e-mail message body is plain text. If you want a different type like HTML or a multipart message, you need to use the MIME extension and specify the type accordingly using Content-Type (e.g. text/html for HTML or multipart/… for a multipart message).
So from the security perspective, there is no way to inject anything harmful (at least not as per specification). Even non-ASCII characters should be handled correctly despite the lacking declaration of the used character encoding.
However, there still may be some flaws in e-mail clients which can be exploited this way. But I doubt that.
Good question. I don't believe you need to escape the body text, but I do know it's possible to add headers to a mail (like a BCC to thousands of addresses) if you allow the user to input a from address. So if you put variables in that, definitely check for newlines (\n and \r) to make sure no additional headers are added.
Think of the body of the email this way: "Mission top secret destination unknown." We may not know what kind of client will read the message, but we can guess that we do not want live, user supplied, unescaped HTML to show up in it. Since many clients read mail in HTML, the best thing to do would be to htmlentities() the user supplied e-mail body.
A method from my escaper class.
<?php
class escaper
{
public function superHtmlEntities($string)
{
return htmlentities($string, ENT_QUOTES | ENT_HTML5, 'UTF-8', true);
}
}
?>
========================================
At minimum, consider something like this and more as you do your research.
<?php
$esc = new Escaper();
$usercontent = $_GET['usercontent'];
mail("dummy#nowhere.tld", "My Subject", $esc->superHtmlEntities("My body with $usercontent included"));
?>
It is not secured against XSS atack because if your mail contains HTML someone can inject it into mail.
The good behaviour is to check and valid data which you expect to have. If I were you I would escape this string. It costs almoust nothing and you don't have to worry about consequences of not using it.
When I try to send a HTML encoded email from PHP, if the subject line contains special chars like "Here's the information you requested", PHP encodes it to read "Here's the information you requested."
How do I fix this?
Here's what the code looks like using PHP mail():
$headers = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";
$headers .= 'To: ' . $mod_params['name'] . '<' . $mod_params['email'] . '>' . "\r\n";
$headers .= 'From: <do_not_reply#a4isp.com>' . "\r\n";
$email_to = $mod_params['email'];
$email_sub = "Here's the Information You Requested";
$body = html_entity_decode("<html><body>" . $email_html_body . "</body></html>");
mail($email_to,$email_sub,$body,$headers);
It gives the same error as running it through the SugarPHPMailer class.
Try this:
$newsubject='=?UTF-8?B?'.base64_encode($subject).'?=';
This way you don't rely on PHP or the MTA's encoding, you do the job, and the mail client should understand it. No special characters will be present in your new subject, so no problems should arise while delivering the email.
I had a similar issue in a Wordpress plug-in I was working on and I racked my brain over and over trying different suggestions from here and in various other Google search results. I finally found a solution that worked in my situation so I'll share it. I will say it was Paul's solution which I tried at first and it didn't work, but the reason was me trying to "shorthand" the solution. In my case just calling html_entity_decode() didn't work. Why? If I had read the PHP doc more closely it would have been obvious. My issue was with encoding on a single quote and the default for html_entity_decode() is 'ENT_COMPAT' which leaves single quotes alone. The solution was to set all the parameters and that worked. In reality I probably could have left off the charset since I was encoding UTF-8, but figured I be thorough.
$decoded_str = html_entity_decode ( $value_to_decode, ENT_QUOTES, 'UTF-8' );
The lesson here is a good one, "Read the docs". I'm not saying that you didn't (you probably did), but lot's of us get in a hurry and gloss over the solution which is sitting there staring us in the face if we'd only look.
If the string really doesn't contain encoded values before you send, take a look at this:
$subject= mb_encode_mimeheader($subject,"UTF-8", "B", "\n");
// or
$subject= mb_encode_mimeheader($subject,"UTF-7", "Q", "\n");
Take a look at these posts related to SugarCRM:
http://www.sugarcrm.com/forums/showthread.php?t=11940
http://www.sugarcrm.com/forums/showthread.php?t=11106&highlight=iso-8859-1
You should use mb_encode_mimeheader, just remember to set before.
mb_internal_encoding("UTF-8"); //has to be set (of course your internal encoding may not be UTF-8).
$subject = mb_encode_mimeheader($subject,'UTF-8','Q');
It will take care of encoding to (the human readable) Quoted-printable when needed and automatically break the subject into the right amount of lines depending on lenght.
Try running the subject line through html_entity_decode(), looks like maybe you have some entities in the subject line.
Submitting the offending block of code often times will ensure you a better response faster. You are likely encoding the text somewhere before this action takes place. As previously suggested you can seek out that action, and correct it, or you can simply decode the subject line before sending the email.
I have a strange issue with encoding, described as follows:
the ù is now shown as ù in the email subject. The email is sent through php mail function.
When viewing the e-mail in the mailbox, it is shown correctly. However, when anybody opens the e-mail, the ù is suddenly changed to ù.
Uw contact met Meeùs
should be
Uw contact met Meeùs
i have already used the encoding.
$emailsubject contains the above mentioned email subject.
$subject=$emailsubject;
$subject=$emailsubject;
$email_message=new email_message_class;
$email_message->SetEncodedEmailHeader("To",$to_address,$to_name);
$email_message->SetEncodedEmailHeader("From",$from_address,$from_name);
$email_message->SetEncodedEmailHeader("Reply-To",$reply_address,$reply_name);
$email_message->SetHeader("Sender",$from_address);
$email_message->SetEncodedHeader("Subject",$subject,"UTF-8");
In localhost it is working properly, but in the webserver it is not working properly. In webserver also encoding is set to utf-8 by default.
What i am doing wrong?
Thanks in advance.
Your code is correct absolutely there is no error in it but its other things failing encoding. As I need message source headers and message to tell you exactly what is happening? I have further no information about are you sending the email as plain text or HTML. But there are generally two issue which are:
Missing Mime-Version
Reason for showing the character wrongly is developers forget to describe the message as MIME Version. if the message is missing the "Mime-Version" header that Internet mail standards require, Webmail will ignore the "charset" header completely, garbling the message unless it's already in the UTF-8 character set.
Showing Subject with Special Characters
As you want to show the subject with utf-8 encoding then you must encode the subject as:
//Setting the Language as Japan
mb_language("ja");
//Converting the string into Japan Encoding
$subject = mb_convert_encoding($subject, "ISO-2022-JP","AUTO");
//Now convert the string to MIME Header type
$subject = mb_encode_mimeheader($subject);
If the above mentioned things doesn't resolve the problem then request you post the RAW Headers of the Email as it will help in better way to resolve issue.
Are you test to change the charset with .htaccess ?
AddDefaultCharset UTF-8
Since you indicate in the comments you are using Joomla 1.5, it seems there is an issue with the phpmailer() library in that version that forces the character set of the mailer—on the message—to send things out using the character set setting of iso-8559-1. To fix this open up the core phpmailer() libary here:
[path to your Joomla install]/libraries/phpmailer/phpmailer.php
Around line 50 there is a setting called $CharSet. Change that to utf-8 if it’s not set to that already:
/**
* Sets the CharSet of the message.
* #var string
*/
var $CharSet = 'utf-8';
You might also want to do search of your Joomla 1.5 codebase for iso-8559-1 to see if a component or library is forcing iso-8559-1 encoding somewhere in the chain of code.
And another setting I would recommend checking is $Encoding around line 63. The default setting seems to be 8bit, but I have had to adjust that in the past to either quoted-printable or base64 to solve some mailing issues on specific setups I was working on.
/**
* Sets the Encoding of the message. Options for this are "8bit",
* "7bit", "binary", "base64", and "quoted-printable".
* #var string
*/
var $Encoding = '8bit';
I suggest you to use joomla mailer class, the could would look like this:
$mailer = JFactory::getMailer();
$mailer->setSender(array($from_address,$from_name));
$mailer->addRecipient($to_address, $to_name);
$mailer->setSubject($subject);
$mailer->setBody("BODY MESSAGE STRING");
$mailer->Send();
It's utf8 by default, and i don't see any reasons for not to use it, if you're using Joomla.
I'm using SwiftMailer to send emails but I have some codification problems with UTF-8 subjects. Swiftmailer uses QPHeaderEncoder as default to encode email headers and the safeMap looks like it has some problems with some UTF-8 French characters. One subject I use contains the word trouvé (found in French) and when the subject gets to the user it shows trouv.
I'd like to use something similar to the NativeQPContentEncoder that's available as content encoders but for headers there's only Base64 and Quoted Printable encoders.
Is there a way to fix this, maybe I'm doing something wrong so I paste the code I'm using here
$message = Swift_Message::newInstance()
// set encoding in 8 bit
->setEncoder(Swift_Encoding::get8BitEncoding())
// Give the message a subject
->setSubject($subject)
// Set the From address with an associative array
->setFrom(array($from => $niceFrom))
// Set the To addresses with an associative array
->setTo(array($to)) ;
Check if in your PHP configuration mbstring.func_overload option has any value other than 0. If yes, change it to 0, reload your webserver and try to send message again.
mbstring.func_overload overrides some string PHP functions and may lead to tricky bugs with UTF-8.
Personally I solved exactly this problem by disabling mbstring.func_overload.
First, make sure you know how is your subject string encoded. If it is not UTF-8 then utf8_encode() it.
Also, make sure you setCharset('utf-8') your message.
I've looked around here but could not find an answer regarding the problem that I am facing.
Most similar to my problems are in this: emails sent with php mail don't show up correctly in outlook , but I checked and the solution did not work for me.
I am basically writing a PHP script that sends out emails, with a table in it. The problem however, is that if I receive it in gmail, the email shows up fine, but it does not even come through to Outlook at all.
Examining the source code of emails that do make it through to Outlook, shows a line break for some reason (again not present in gmail)
Eg:
<td> xyz#aaa
tt.com </td>
When it should show up as:
<td> xyz#aaatt.com </td>
In my php code, I even try to remove the line returns and spaces (as there should be no spaces in emails)
$rmv = array("\n");
$lead_email = str_replace($rmv, "", $lead_email);
$rmv = array("\r");
$lead_email = str_replace($rmv, "", $lead_email);
$rmv = array(" ");
$lead_email = str_replace($rmv, "", $lead_email);
For reference, my mail header is as follows:
$headers = 'MIME-Version: 1.0' . "\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\n";
$headers .= 'From: helpdesk#viatechcrm.com' . "\n";
Btw should I use iso-8859-1 or utf-8? I occasionally encounter names with European characters.
Any help greatly appreciated!
EDIT: So I was examining the source code, and found something interesting. The message is really long, but it only shows 3-4 lines. I found that it gets cut off right about 991 characters, thus the email breaking up.. Is this something to do with the Mime-Version 1.0?
How can I increase the number of characters it can receive? I tried adding '\r\n' after every table row, but one of the 4 emails still does not show up for some reason
EDIT 2: Thanks everyone for the help! I finally figured it out, in a forum post dated back in 2009. For future reference, refer to the last posting:
http://forums.devarticles.com/php-development-48/formatting-a-newline-line-break-in-php-html-output-5274.html
You should use UTF-8 if you have non-alphanumeric characters. You should end each header line with a "\r\n", not just a plain "\n". Not sure if this will fix your problem as I can't test, but it is something that you should fix nontheless.
It sounds like you have only added "\r\n" to the HTML part of your message. All header lines must end in "\r\n", not just the lines in the body. Some clients and servers will cope with just "\n" but they really don't have to (see RFC 2822), hence the inconsistencies between Gmail and Outlook.