在电子邮件正文中引用/转义变量

13

我感觉有些尴尬,因为我正在使用PHP生成邮件正文时没有转义变量。在HTML中,我使用htmlspecialchars()或类似的函数,在命令行中使用escapeshellarg(),但是在邮件中呢?例如像这样:

<?php
$usercontent = $_GET['usercontent'];
mail("dummy@nowhere.tld", "My Subject", "My body with $usercontent included");
?>

一个可能的攻击者可以用上面的脚本做什么,我该如何保护自己免受这种攻击?或者PHP mail()是否安全?请参考以下示例:只影响正文(没有标题!)Content-Type是text/plain;提供一些关于答案的证明将会很好;MTA是一个带有“/usr/sbin/sendmail-t-i”的后缀sendmail。

邮件函数的风险在于其第四个参数,只要不与用户生成的内容一起使用,我认为您足够安全。无论如何,我建议使用第三方库,例如Swiftmailer http://swiftmailer.org/。 - arraintxo
关于涉及第四个参数的安全问题,您也可以在这里查看:https://dev59.com/HW445IYBdhLWcg3we6Z9 - arraintxo
感谢您的评论,关于其他参数的安全问题,我很清楚,我只是对注入多部分邮件之类的主体感兴趣。 - Trendfischer
4个回答

7
基本的电子邮件消息正文是纯文本。如果您想使用其他类型(例如HTML或多部分消息),则需要使用MIME扩展并使用Content-Type指定相应的类型(例如,对于HTML使用text/html,对于多部分消息使用multipart/…)。
因此,从安全的角度来看,无法注入任何有害内容(至少按照规范是这样)。即使缺少所使用字符编码的声明,非ASCII字符也应该被正确处理。
但是,仍然可能存在某些电子邮件客户端存在漏洞,可以利用这种方式进行攻击。但我不太确定。

在我看来,这是目前为止最好的答案。Content-Type text/html 应该很清楚,multipart/... 可能会有危险。虽然我的疑虑还没有得到解决。但是,一行中只有一个“.”,比如“\r\n.\r\n”会怎样呢?这可能会有危险吗? - Trendfischer

0
将电子邮件正文视为“任务绝密目的地未知”。我们可能不知道哪种客户端会阅读该消息,但我们可以猜测我们不希望出现实时、用户提供的、未转义的HTML。由于许多客户端以HTML格式阅读邮件,最好的做法是对用户提供的电子邮件正文进行“htmlentities()”处理。
来自我的转义类的一个方法。
<?php
class escaper
{
    public function superHtmlEntities($string)
    {
        return htmlentities($string, ENT_QUOTES | ENT_HTML5, 'UTF-8', true);
    }
}
?>

========================================

至少在你进行研究时,考虑类似这样的东西以及更多。

<?php
$esc = new Escaper();

$usercontent = $_GET['usercontent'];
mail("dummy@nowhere.tld", "My Subject", $esc->superHtmlEntities("My body with $usercontent included"));
?>

转换编码以转义HTML应该是最少的。同意。至少在内容类型为“text/html”的情况下。但要小心字符集,并确保双重编码没有问题。在某些验证库中,您已经对输入进行了编码。 - Trendfischer

0

它没有防止XSS攻击,因为如果您的邮件包含HTML,某人可以将其注入邮件中。

良好的行为是检查和验证您期望拥有的数据。如果我是你,我会转义这个字符串。它几乎不花费任何代价,而且您不必担心不使用它的后果。


是的,这就是我自己会给出的答案;-) 但是什么类型的转义是合适的呢? - Trendfischer
1
只是为了“以防万一”或者“不会有害处”而做某件事,并不属于工程学,这只是猜测罢了。我更喜欢知道实际需要做什么,为什么需要这样做。 - Nicolas

0

好问题。我认为您不需要转义正文,但是如果允许用户输入发件人地址,则可以添加邮件头(例如将密送抄送给数千个地址)。因此,如果在其中放置变量,请务必检查换行符(\n\r),以确保不会添加其他标题。


我也考虑过转义换行符,但变量不在正文开头。如何添加附加标头?我的关注点更多地在于理解问题,但还是谢谢你的回答。 - Trendfischer
所以我认为个人来说,你不用转义也可以。 - Rijk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接