假设我的视图页面上有以下代码(在asp.net mvc 3 razor中):
<a href='https://example.com/search?q=@Url.Encode(Model.UserInput)'>Click here</a>
Model.UserInput
是一个用户输入字符串,可以包含任何字符。
在html注入和跨站点脚本方面,这是否完全安全?或者我也应该在对URL进行编码之后对查询字符串进行HTML编码吗?
当然,通常我会在此阶段之前消除危险输入,但这不是重点。
答案 0 :(得分:3)
你必须 URL编码查询字符串参数;你不能也不应该以原始形式传递它们。参数(您的案例中的用户输入)可能包含特殊的URI字符,例如?
,=
和&
。如果没有编码,用户输入hansel&gretel
将变为https://example.com/search?q=hansel&gretel
; q
查询字符串参数仅包含hansel
。
此外,您必须 HTML编码任何HTML ;甚至那些在attrbute值内使用的片段。这是为了确保在HTML中具有特殊含义的任何字符(例如<
,>
和&
)转换为各自的HTML实体。网址编码消除了大多数这些情况,但你仍然应该养成这个习惯。
请注意'
旁路网址编码!!它(我认为)也将通过HTML编码。不要将'
用作HTML属性分隔符,也不要确保HTML编码功能将'
转换为'
或'
。
答案 1 :(得分:1)
这是完全安全吗
也许是,也许不是。我会用另一个角度处理这个问题,暂时忽略安全......
网址编码有一个目的:percent-encoding(它的实际名称是)一个网址。想象一下,“url编码”将用<space width='1'>
替换所有空格而不是实际的%20
或者它现在所做的任何事情。在我们的虚构示例中,网址“...?q=foo bar
”将成为“...?q=foo<space width='1'>bar
”并且是正确的“网址编码”网址。这可能在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中你需要转义像"
和<
之类的字符,在RTF文件中你甚至需要转义,甚至其他字符串/字符(我实际上并不知道)\
会变成\\
或类似内容,在CSV文件中,您需要在字段值和JSON输出中转义,
或;
,您需要一个包含{{1}的字符串要转义为"
。每种类型的输出(格式)都需要它自己的转义/编码。
您现在正在做的是“嵌套上下文”,您正在“HTML上下文”中嵌套“网址上下文”。所以你必须相应地转义/编码。