安全问题:电子邮件发送者可被伪造

3
我有一个Web服务器,可以让我发送电子邮件(使用PHP),而且我可以将发件人设置为任何人...为什么这是可能的?这不是安全问题吗?
使用PHP邮件功能。
这种情况可能存在一些安全隐患。攻击者可以利用此漏洞伪造邮件发送者身份,从而进行钓鱼攻击或其他恶意行为。建议在编写代码时注意验证发件人身份,并确保只接受合法的发件人地址。同时,使用加密协议(如TLS)来保护邮件的传输过程中的数据安全。
// To send HTML mail, the Content-type header must be set
$headers  = 'MIME-Version: 1.0' . "\r\n";
$headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

// Additional headers
$headers .= 'To: Jon Ives <jives@apple.com>' . "\r\n";
$headers .= 'From: Tim Cook <tcook@apple.com>' . "\r\n";

$message = 'I need you to create a clear iPhone.';

// Mail it
mail($to, $subject, $message, $headers);

在上面的例子中,我可以假装将电子邮件发送给任何人,我以为当你发送电子邮件时......发送者地址是可靠的......为什么欺骗发件人如此容易。
编辑
———————
有没有代码可以用来防止我收到欺骗性的电子邮件?
另外,是否有一种方法可以欺骗电子邮件的日期和时间?还是那是由接收服务器生成的?
例如,如果我添加了
$headers .= 'Date: 2010-1-2 12:32:13' . "\r\n";

12
欢迎来到邮件工作原理介绍。 - John Conde
我曾经利用这个知识从God@Heaven.Above发送过电子邮件 ;) - Izkata
4
发件人地址可靠的观念被称为“天真的误解”。这就是为什么我们需要像SPF和DKIM这样的机制,它们只能证明某个允许使用这些服务器的人发送了邮件,而不能保证发送地址所声称的人就是实际发件人。 - Sammitch
@JohnConde 你能否伪造邮件头里的时间和日期? - Arian Faurtosh
4
你可以通过在邮件上写上不同的姓名和地址来达到同样的效果。 耸了耸肩 - Boann
显示剩余4条评论
2个回答

4
你所说的是伪造消息,虽然有可能发送,但接收者极不可能接收到该消息。有安全措施可以防止消息伪造:
  1. DomainKeys
  2. DKIM
  3. SPF
  4. SenderID
DomainKeys已被弃用,推荐使用DKIM。两者非常相似。SO帖子"DomainKeys与DKIM的区别?"描述了它们之间的区别。
SPF和SenderID有时会混淆,但它们是不同的;请参阅SPF: SPF vs SenderID
这取决于收件人的SMTP服务器来实现和利用这些技术。例如,如果邮件接收成功但SPF检查失败,该邮件将被标记为垃圾邮件并进入“垃圾邮件文件夹”,但该邮件仍然被接受。更进一步,SMTP服务器还可以验证邮件的DKIM签名;如果验证失败,则不会接受该邮件。这些策略和邮件路径由接收邮件服务器/客户端确定并且差异很大。
发件人策略框架(SPF)/ SenderID
发件人策略框架(SPF)是一种电子邮件验证系统,旨在通过验证发件人IP地址来检测电子邮件欺骗,这是一种常见的漏洞,以防止电子邮件垃圾邮件。SPF允许管理员通过在域名系统(DNS)中创建特定的SPF记录(或TXT记录)来指定哪些主机被允许从给定域名发送邮件。邮件交换器使用DNS来检查来自给定域名的邮件是否是由该域名的管理员授权的主机发送的。
来源:维基百科 与SPF相反,SenderID验证的是所谓的负责人地址(PRA),请参见RFC 4407
简单来说,这是一个DNS检查,询问“IP地址X是否可以发送Y域的邮件?”
想象这种情况:Susie写了一封信给Victoria。在此之前,Susie告诉Victoria只有她的兄弟John和她自己会给她送信。所以Susie把信交给了John,并告诉他把信走到街上给Victoria。Victoria听到敲门声,发现是John带着Susie的信来了;由于之前的协议,Victoria接受了这封信。几天后,Susie又写了一封信给Victoria,但是John生病不能送信了;于是Susie请邻居Rick把信走到街上给Victoria。Rick敲了Victoria的门并说他有一封来自Susie的信。Victoria拒绝了这封信并没有接受它(或者她可能把它放在桌子上以便稍后验证它是否“有机会是真实的”),因为她期望只有Susie和John会给她送信。
example.com的示例SPF记录:
spf2.0/mfrom ptr:mx.example.com +a +ip4:192.168.1.1 -all

这个SPF记录表示只有来自服务器mx.example.com、属于example.com的所有A记录和IPv4地址192.168.1.1的邮件才能发送example.com的电子邮件,其他人都不行(-all)。
DomainKeys Identified Mail(DKIM)/ DomainKeys
我将重点介绍DKIM,因为DomainKeys已经半废弃了,但前提是相同的。
“域名标识邮件”(DKIM)是一种将域名与电子邮件消息相关联的方法,从而允许某个人、角色或组织声称对该消息负有某些责任。通过在消息头中添加DKIM-Signature:字段,签署者独立于实际作者或接收者,可以建立关联。验证器使用DNS恢复签名者的公钥,然后验证签名是否与实际消息内容匹配,以此来声明签名者的责任。

DKIM与SPF不同,因为SPF仅与DNS相关,而DKIM是存在于邮件本身的签名。如果你熟悉公钥密码学的概念,那就是DKIM的基本原理。发件人有一个用于加密信息的私钥;它通过DNS TXT记录使公钥可用于解密。

简单地说,DKIM的问题是:"我接收到的信息确实来自发件人X吗?"

想象一下这种情况:Susie给Victoria写信。除了信件外,还有一个由Susie设计的加密代码。Susie让Rick将信交给Victoria。Rick敲响Victoria的门,呈现带有加密代码的信件。在接受信件之前,Victoria拿出她的"解密书"(像电话簿一样 - 公开可访问的解密代码列表,但不用于加密);她解密代码以发现它实际上是Susie的签名,然后接受Rick的消息。请记住,除非Susie发布她的加密密钥,否则没有人可以伪造Susie的签名。


有没有办法伪造电子邮件中的日期和时间?

有点。发送日期就像您所拥有的一样:

$headers .= 'Date: 2010-1-2 12:32:13' . "\r\n";

然而,接收的SMTP服务器将总是在邮件上打上自己的时间戳。根据邮件服务/客户端的不同,可能会读取Date头部,或者读取另一个元时间戳(例如接收的SMTP服务器添加到头部的时间戳)。例如,我认为gmail会尊重发件人放置的Date头部 - 我曾经看过1970年1月1日(Unix纪元开始)的电子邮件。这可能是个坏主意,特别是对于收件箱中有很多内容的邮箱 - 该消息可能会在中间或最后丢失。

0
远程服务器被解析为apple.com,因此它总是会到那里。
现在所有远程服务器知道的只是您的SMTP地址(它并不关心)。
由于发件人在电子邮件头中被提及,所以正在使用该发件人。
结论:这就是电子邮件的工作方式。
我希望我解释得尽可能清楚易懂。

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