MailAddress类是否存在XSS漏洞?

3

如果我将用户输入解析为一个电子邮件地址,并转换成MailAddress类:

var mailString = Request.QueryString["mail"];
var mail = new MailAddress(mailString);

如果我稍后以任何方式输出MailAddress对象,是否仍有跨站脚本攻击的可能性?例如通过WebForms中的Literal控件:

litMessage.Text = "Your mail address is " + mail.Address;

即使我已经通过解析字符串来确保地址是有效的电子邮件地址,是否有必要对输出进行过滤?

据我所知,邮件地址的RFC非常复杂,因此我不确定.NET认为有效的邮件地址中是否可以隐藏跨站脚本。

编辑:
MSDN表示,><括号在电子邮件地址中是允许的:

如果您将地址置于角括号中,则地址参数可以包含显示名称和相关联的电子邮件地址。例如:"Tom Smith <tsmith@contoso.com>"

因此问题仍然存在:这是否足以防范XSS攻击,或者MailMessage类是否会执行任何操作以转义危险部分。

2个回答

0

一般来说,您不应该需要稍后验证输出。但是,出于以下原因,我始终建议您这样做:

  1. 您的应用程序中可能存在漏洞,无法正确验证输入。攻击者可能会发现这一点,并将其用于XSS攻击。当许多不同的开发人员在应用程序上工作时,这种情况尤其可能发生。
  2. 数据库中可能存在旧数据,这些数据存储在实施/更新输入过滤器之前。这可能包含恶意代码,可用于XSS攻击。
  3. 攻击者非常聪明,通常可以找到打败过滤器的方法。微软非常注重防止这种情况发生,但永远不会完美。如果他们面对出站过滤器和入站过滤器,那么攻击者的工作就会更加困难。

我知道不断过滤很烦人,但这样做有很大的价值。在今天的世界中,必须采取深度防御策略。

编辑:

抱歉,我没有真正回答您问题的第二部分。根据文档,我没有印象API专注于净化,而是专注于验证有效格式。因此,我不知道是否安全依赖它进行安全目的。

然而,编写自己的过滤器并不是很困难,如果发现漏洞,可以立即更新。首先,通过一个好的正则表达式过滤器(参见:正则表达式电子邮件验证),对地址进行处理,然后递归删除电子邮件地址中的每个非有效字符(这些字符在此时不应该出现,但为了全面性和在其他地方重用类,还是要进行处理),最后转义每个具有HTML含义的字符。我强调递归应用过滤器,因为攻击者可以利用非递归过滤器实施类似以下代码的攻击:

<scr<script>ipt>

注意,非递归过滤器会删除一次出现的<script>,但保留外部的出现。


如果MailAddress类已经确保只接受有效的字符串,那么使用额外的正则表达式过滤器有什么意义呢?我的问题是,有效的电子邮件地址是否可能包含可以通过此方式绕过验证的XSS攻击。当然,在创建输出时转义HTML字符从来都不是一个坏主意,你说得对。但是我想知道,如果使用MailMessage对象,这种类型的攻击是否会成为可能。了解潜在攻击者可能具有的选项从来都不是一个坏主意。 - magnattic
你说得对,使用MailAddress类时不应该需要添加正则表达式过滤器。我在这里包含它是为了完整地开发一个净化器。话虽如此,在高安全性环境中,我们不喜欢信任专有/闭源代码,因为我们无法检查其漏洞。出于这个原因,我们编写自己的代码。至于通过MailMessage进行攻击,我不知道是否存在任何攻击,但这并不意味着不可能,特别是如果您以作者未预料到的方式使用该类。 - Freedom_Ben
如果有人攻击MailAddress成功,他们很可能不会放弃,因为在地下黑市上它的价值非常高。我刚听说有一个针对Java 7的黑客攻击被以5万美元的价格出售。一旦被公开,它们就毫无价值了。 - Freedom_Ben

0
需要对输出进行清理吗?
你不需要“清理”输出,而是需要对其进行编码。每个字符串在输出到HTML文档之前都需要进行HTML编码,因此,如果邮件地址中有一个<字符,那么它也无关紧要——结果在HTML源代码中会得到&lt;,并且在页面上将正确地显示为文字<。
许多ASP.NET控件会自动处理HTML转义,但默认情况下,Literal不会这样做,因为它可以用于显示标记。但是,如果您将Literal控件的Mode属性设置为Encode,那么像您所做的那样设置Text就完全没有问题。

无论您认为所使用的值是否能够包含一个<字符,您都应确保每次将内容放入HTML页面时都使用安全的HTML编码输出。这是一个关注点分离的问题:HTML输出代码对HTML格式化非常了解,但它不应该知道电子邮件地址或其他应用程序字段中哪些字符是合法的。

如果因为您认为值是“安全的”而省略了转义,会在输出阶段和输入阶段之间引入一种隐式而脆弱的耦合,这使得很难验证代码是否安全,并在修改时容易使其变得不安全。


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