0

假设我的视图页面上有以下代码(在 asp.net mvc 3 razor 中):

<a href='https://example.com/search?q=@Url.Encode(Model.UserInput)'>Click here</a>

Model.UserInput是可以包含任何字符的用户输入字符串。

就 html 注入和跨站点脚本而言,这完全安全吗?或者我应该在 URL 编码之后对查询字符串进行 HTML 编码吗?

当然,通常我会在这个阶段之前消除危险的输入,但这不是重点。

4

2 回答 2

3

必须对查询字符串参数进行 URL 编码;您不能也不应该以原始形式传递它们。参数(在您的情况下为用户输入)可能包含特殊的 URI 字符,例如?,=&. 没有编码,用户输入hansel&gretel变成https://example.com/search?q=hansel&gretel; 查询q字符串参数仅包含hansel.

此外,您必须对任何 HTML 进行 HTML 编码;甚至那些在属性值中使用的片段。这是为了确保如果任何在 HTML 中具有特殊含义的字符,例如<,>并被&转换为它们各自的 HTML 实体。Url 编码消除了大多数这些情况,但您仍然应该养成这种习惯。

请注意,'绕过 URL 编码!它也会(我认为)通过 HTML 编码。不要'用作 HTML 属性分隔符或确保您的 HTML 编码函数转换'&#039;&apos;.

于 2012-07-18T21:51:08.010 回答
1

这完全安全吗

也许是,也许不是。我会从另一个角度解决这个问题,暂时忽略安全性......

URL 编码有一个目的:百分比编码(它的实际名称是什么)一个 url。想象一下,“url 编码”将替换所有空格,<space width='1'>而不是实际的%20或它现在所做的任何事情。...?q=foo bar在我们想象的例子中,url“ ”将变成“ ...?q=foo<space width='1'>bar”,并且是一个正确的“url编码”url。这在 PDF 或 CSV 文件或您要创建的任何其他类型的输出中可能很有用,但在 HTML 中这会引起麻烦。在您的情况下,因为'这将“结束”href属性1'>作为垃圾离开。

<a href='https://example.com/search?q=foo<space width='1'>'>

因为您的输出是针对 HTML 的,所以实际上,至少恕我直言,您应该这样做HTMLEncode(URLEncode(MyUrl))(伪代码)。

记住这一点:转义总是在特定的上下文中完成。对于 SQL,您需要一些类似“mysql_real_escape”的东西来转义引号等,以避免 SQL 注入漏洞。在 HTML 中,您需要转义诸如"and之类的字符<,在 RTF 文件中,您甚至需要转义其他字符串/字符,例如(我实际上不知道)\会变成\\或类似的东西,在 CSV 文件中您需要转义,;在字段值和 JSON 输出中,您需要一个包含 a 的字符串"以转义为\". 每种类型的输出(格式)都需要自己的转义/编码。

您现在正在做的是“嵌套上下文”,您将“url 上下文”嵌套在“HTML 上下文”中。所以你必须相应地转义/编码。

正如 TrueBlue 所证明的那样,它并不安全。

于 2012-07-18T21:32:24.670 回答