在 mail() 中使用的转义字符串

发布于 2024-12-14 13:44:41 字数 435 浏览 1 评论 0原文

当然,当使用 MySQL 时,您可以使用 mysqli_real_escape_string() 并检查收到的输入类型是否是您期望的类型(字符串、数字等),并且您可以非常确定可以将其用作输入到 mysqli_query() 相当安全......对吗?

好吧,问题是:

  • 转义将在 mail() 中使用的字符串的最佳方法是什么?
  • 如果电子邮件收件人是在文本字段中输入的电子邮件地址,我应该注意哪些事项以避免注入或利用?

我很清楚如何做到这一点,但我正在深入研究这个主题的最佳实践,以了解我是否遗漏了某些内容,或者是否有更好的方法。


编辑:这个问题的想法不是要得到THE答案,而是制定一个全面的协作列表,列出使用 PHP 发送电子邮件时需要注意的所有事项。

Sure thing, when using MySQL you use mysqli_real_escape_string() and check that the type of input received is the kind you expect (string, number, etc) and you can be pretty sure you can use it as input to mysqli_query() quite securely... right?

Well, the questions are:

  • What is the best way to escape a string that's going to be used in mail()?
  • If the email recipient will be the email address entered in a text field, what things should I be careful about to avoid injections or exploits?

I have a pretty good idea how to do this but I'm digging into best practices on this subject to know if I'm missing something, or if there's a better way.


EDIT: The idea of this question is not to have THE answer, but to make a comprehensive collaborative list of all the things to take care of when doing email with PHP.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

凤舞天涯 2024-12-21 13:44:41

电子邮件注入背后的想法是,攻击者在电子邮件标头中注入换行符 (LF),因此他可以添加任意数量的标头。剥离这些换行符将保护您免受这种攻击。有关详细信息,请检查 http://www.phpsecure.info/v2/article/ MailHeadersInject.en.php

最佳实践是依赖编写良好、经常更新且广泛使用的代码。为此,我建议使用 PEAR_MAILZend_Mail

如果您不想加载这些模块或者您需要让事情变得非常简单。您可以从这些模块中提取过滤功能。尽管我确实建议使用它们并经常更新库,这样如果将来出现新的攻击,您只需要更新您的库(Pear 或 Zend)即可。

这是 Pear Mail 包中清理标头的函数:

function _sanitizeHeaders(&$headers)
{
    foreach ($headers as $key => $value) {
        $headers[$key] =
            preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
                         null, $value);
    }
}

Zend_Mail 对电子邮件、姓名和其他字段使用不同的过滤器:

function _filterEmail($email)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
                  '"'  => '',
                  ','  => '',
                  '<'  => '',
                  '>'  => '',
    );

    return strtr($email, $rule);
}

function _filterName($name)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
                  '"'  => "'",
                  '<'  => '[',
                  '>'  => ']',
    );

    return trim(strtr($name, $rule));
}

function _filterOther($data)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
    );

    return strtr($data, $rule);
}

The idea behind email-injection is that attacker inject line feed (LF) in the email headers and so he adds as many headers as he wants. Stripping those line feeds will protect you from this attack. For detailed info check http://www.phpsecure.info/v2/article/MailHeadersInject.en.php

The best practice is to rely on a well-written, frequently updated and widely-used code. For that I would suggest using PEAR_MAIL OR Zend_Mail

If you don't want to load those modules or you need to keep things very simple. You can extract the filtering functionality from those modules. Although I do recommend to use them and frequently update the library so that if new attack appears in future you will just need to update your library (Pear or Zend) and you are done.

This is the function that sanitize headers in Pear Mail package:

function _sanitizeHeaders(&$headers)
{
    foreach ($headers as $key => $value) {
        $headers[$key] =
            preg_replace('=((<CR>|<LF>|0x0A/%0A|0x0D/%0D|\\n|\\r)\S).*=i',
                         null, $value);
    }
}

Zend_Mail uses different filter for email,name and other fields:

function _filterEmail($email)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
                  '"'  => '',
                  ','  => '',
                  '<'  => '',
                  '>'  => '',
    );

    return strtr($email, $rule);
}

function _filterName($name)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
                  '"'  => "'",
                  '<'  => '[',
                  '>'  => ']',
    );

    return trim(strtr($name, $rule));
}

function _filterOther($data)
{
    $rule = array("\r" => '',
                  "\n" => '',
                  "\t" => '',
    );

    return strtr($data, $rule);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文