Quoting/Escaping variables in mail body
Asked Answered
L

4

13

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("[email protected]", "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"
Lipography answered 17/4, 2013 at 12:7 Comment(3)
The riskier use of mail function is on it's 4th parameter, and as long as you don't use it with user generated content I think you are safe enough to go with it. Anyway, I would recommend to use a third party library like Swiftmailer swiftmailer.orgKidron
For the security issues involving the 4th parameter, you can also take a look in here: #4834837Kidron
Thanks for the comments, about the security issues from the other parameters, I am well aware, I am just interested in the body like injecting multi part mails or something like this.Lipography
E
7

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.

Elutriate answered 17/4, 2013 at 16:27 Comment(1)
Imho, this is the best answer so far. Content-Type text/html should be clear, multipart/... could be dangerous. Although, my doubt isn't satisfied, yet. What is with a single "." in a line, like "\r\n.\r\n"? Could this be dangerous?Lipography
H
0

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.

Horrorstruck answered 17/4, 2013 at 12:10 Comment(2)
Yes, this would be the answer I would have given myself ;-) But what type of escaping would be appropriate?Lipography
Doing something "just in case" or because "it can't harm" is not engineering though, it is guessing. I much prefer to know what actually needs to be done, and why.Callan
C
0

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.

Cuneo answered 17/4, 2013 at 12:11 Comment(2)
I thought about escaping newlines too, but the variables are not at the beginning of the body. How should one add additional headers with it. My concern is more in understanding the problem, but thanks for the answer.Lipography
So I think you're ok without escaping personally.Cuneo
J
0

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("[email protected]", "My Subject", $esc->superHtmlEntities("My body with $usercontent included"));
?>
Jinn answered 30/4, 2015 at 17:39 Comment(1)
Escaping HTML should be the minimum. Agreed. At least at content-type text/html. But be careful with the charset and be sure, double encoding is ok. On some validation libraries, you already have encoded input.Lipography

© 2022 - 2024 — McMap. All rights reserved.