3

考虑到我将用户输入(应该是电子邮件地址)解析到MailAdress类中:

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

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

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

即使我通过解析字符串确保地址是有效的电子邮件地址,是否有必要清理输出?

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

编辑:
MSDN说,>电子邮件<地址中允许使用括号:

如果将地址括在尖括号中,地址参数可以包含显示名称和关联的电子邮件地址。例如:“汤姆·史密斯 <tsmith@contoso.com>”

所以问题仍然存在,这是否足以应对 XSS 攻击和/或MailMessage该类是否采取任何措施来逃避危险部分。

4

2 回答 2

0

是否有必要对输出进行消毒

您不会“清理”输出,而是对其进行编码。您输出到 HTML 文档中的每个字符串都需要进行 HTML 编码,因此,如果<邮件地址中有一个字符,则无关紧要 -&lt;作为结果,您会进入 HTML 源代码,并且会正确显示为页面上的文字<

许多 ASP.NET 控件会自动为您处理 HTML 转义,但Literal默认情况下不会,因为它可用于显示标记。但是,如果您将控件的Mode属性设置为,那么设置您正在做的事情就很好了。LiteralEncodeText

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

因为您认为该值是“安全的”而忽略转义会在输出级和输入级之间引入隐式且脆弱的耦合,从而难以验证代码是否安全,并且在您进行更改时很容易使其不安全。

于 2013-04-17T10:04:03.847 回答
0

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

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

我知道不断过滤很痛苦,但这样做有很多价值。在当今世界,纵深防御战略是必要的。

编辑:

对不起,我没有真正回答你问题的第二部分。根据文档,我没有得到这样的印象,即 API 专注于清理和验证有效格式一样多。因此,我不知道出于安全目的依赖它是否安全。

但是,编写自己的消毒剂并不难,如果发现缺陷,可以立即更新。首先通过一个好的 RegEx 过滤器运行地址(请参阅:Regex 电子邮件验证),然后递归删除电子邮件地址中的每个无效字符(此时不应通过这些字符,但这样做是为了全面性,以防您想重用其他地方的类),然后用 HTML 含义转义每个字符。我强调过滤器的递归应用,因为攻击者可以利用具有以下内容的非递归过滤器:

<scr<script>ipt>

请注意,非递归过滤器将删除中间出现的<script>并保留外部出现的完整。

于 2013-04-16T17:52:18.597 回答