验证您的网站

9
除了下面列出的内容,还有什么需要验证的吗?这是我的问题。
对于网站的任何输入都需要进行适当的验证非常重要:
- 文本框等 - 使用.NET验证器(如果验证器不合适,则使用自定义代码) - 查询字符串或表单值 - 使用手动验证(强制转换为特定类型,边界检查等)
这与XSS可能揭示的问题有关。
基本上,您必须验证任何潜在被篡改的输入:
- 表单回发(主要是.NET控件 - 可以使用.NET验证控件进行验证。此外,如果您在所有页面上启用了请求验证,则可以降低风险) - 查询字符串值 - Cookie值 - HTTP标头 - ViewState(只要启用了ViewState MAC,系统会自动为您完成) - JavaScript(所有JS都可以查看和更改,因此需要确保没有关键功能由JavaScript处理 - 即始终启用服务器端验证)

1
同意邪恶的用户必须被制止。 - Anicho
4
看起来你已经全面考虑到了,我会在浏览器中关闭JavaScript并确保所有功能仍然可用,并且可以通过服务器端代码处理任何恶意输入。 - Denys Wessels
1
任何可能来自恶意来源的东西 - 实际上是发送到服务器的所有内容,包括URL。 - Anders Marzi Tornblad
@Rook,没有其他的要求,只是想在周五结束前看看是否还有其他人能指出什么。我相信你已经涵盖了大部分内容,如果是这样,你将得到答案核对的勾选:)。 - Anicho
1
处理请求时,有时我会使用if(Request.IsLocal) - ShadowG
显示剩余2条评论
2个回答

5

Web应用程序可能会出现很多问题。您的列表非常全面,尽管有些重复。http规范只规定了GET、POST、Cookie和Header。有许多不同类型的POST,但都在请求的同一部分中。

对于您的列表,我还会添加与文件上传有关的所有内容,这是POST的一种类型。例如,文件名、mime类型和文件内容。我建议使用网络监控应用程序(如Wireshark),并将请求中的所有内容视为潜在的危险因素。

永远不会有一个适合所有验证函数的解决方案。如果您正在合并SQL注入和XSS清理功能,那么您可能会遇到麻烦。我建议使用自动化测试您的网站。像Sitewatch这样的免费服务或skipfish这样的开源工具将检测您错过的攻击方法。

此外,顺便说一句。传递带有MAC和/或加密的视图状态是对密码学的严重误用。密码学是在没有其他解决方案时使用的工具。通过使用MAC或加密,您打开了攻击者通过暴力破解该值或使用诸如Oracle填充攻击之类的工具来利用您的大门。视图状态应由服务器跟踪,结束故事。


感谢您关于视图状态和MAC的提示,我会进一步了解这个。 - Anicho
强烈建议您始终启用MAC验证。它可以很好地防止欺骗攻击,即当攻击者提供通常不允许的值时。来源:http://aspnetresources.com/articles/ViewState - Anicho
2
@Anicho 我并不是建议在视图状态中禁用 MAC,我是说这是一种根本上不安全的解决问题的方法。提出视图状态这个想法的人显然对安全性缺乏理解。 - rook
谢谢你的帮助,伙计。帮了我大忙了 : ) 。还得等3个小时,唉。 - Anicho

1

我建议以一种与您此处使用的方式正交的方式来看待问题(因此不是不兼容的,您可以用两种方式检查它,以防您用一种方法捕获另一种方法错过的情况)。

任何验证中重要的两个方面是:

  1. 您关注的内容。
  2. 传递给另一层的未更改的内容。

现在,到目前为止,您提到的大多数事情都符合第一类。忽略的Cookie属于第二类,如果您使用Server.Execute或类似的方法将查询和提交信息传递给另一个处理程序,则也属于第二类。

第二类别最具争议性。

一方面,如果给定的处理程序(.aspx页面,IHttpHandler等)忽略了可能在将来某个时候由另一个处理程序使用的Cookie,则主要由该其他处理程序来验证它。

另一方面,总是有一个假设其他层有安全漏洞且不应相信它们是正确的方法很好,即使您自己编写了它们(尤其是您自己编写的!)

一个中间地带的立场是,如果有可能存在5种不同的状态,一些持久数据可以合法地存在于其中3种状态,即使对于特定的代码而言,这并不会对其造成风险,它也可能验证它是否处于这三种状态之一。

完成这一步后,我们将集中精力处理第一类。

查询字符串、表单数据、回发、标头和 cookie 都属于来自用户的相同类别的东西(无论他们是否知道)。实际上,它们有时是从不同角度看待同一件事情的不同方式。

其中有一个子集,我们将以任何方式实际处理它。

对于每个这样的项目,都有一系列合法值。

在此基础上,这些项目作为整体还有一系列合法的值组合。

因此,验证变成了以下几点:

  1. 确定我们要处理哪些输入。
  2. 确保该输入的每个组件本身都是有效的。
  3. 确保组合是有效的(例如,不发送信用卡号可能是有效的,但不发送信用卡号但将付款类型设置为“信用卡”可能是无效的)。
现在,当我们谈到这个问题时,通常最好不要尝试捕捉特定的攻击。例如,在传递给 SQL 的值中避免使用 ' 并不是一个好办法。相反,我们有三种可能性:
  1. 在值中使用 ' 是无效的,因为它不属于那里(例如,一个只能是 "true" 或 "false" 的值,或者来自一个值列表的集合,其中没有一个包含 ')。在这里,我们捕获了它不在合法值集合中的事实,并忽略攻击的具体性质(从而也保护我们免受其他我们甚至不知道的攻击!)。

  2. 作为人类输入是有效的,但不是我们将要使用的。一个例子是一个大数字(在某些文化中,' 用于分隔千位数)。在这里,我们将 "123,456,789" 和 "123'456'789" 都规范化为 123456789,并且不关心之前的样子,只要我们可以有意义地这样做(输入不是 "fish" 或超出手头情况的合法值范围的数字)。

  3. 这是有效的输入。如果您的应用程序在名称字段中阻止撇号以尝试阻止 SQL 注入,则存在真实姓名带有撇号的情况,因此它是有缺陷的。在这种情况下,我们认为 "d'Eath" 和 "O'Grady" 是有效的输入,并通过适当转义(最好使用数据访问 API 来完成此操作)来处理 ' 在 SQL 中的重要性。

ASP.NET中第三点的一个经典例子是使用<>阻止“可疑”输入的代码,这会导致许多ASP.NET页面出现错误。当然,与其不适当地接受它而出现错误,阻止它而出现错误要好得多,但默认设置适用于没有考虑验证并试图防止他们自己受到严重伤害的人。由于您正在考虑验证,因此应考虑是否适当关闭自动验证,然后根据您的特定用途以适当的方式处理<>

还要注意,我没有提到javascript。我不验证javascript(除非我实际上收到了它),我忽略它。我假装它不存在,然后我就不会错过可能被篡改的验证案例。在这个层面上也假装你的不存在。最终,客户端验证是为了节省善良的人犯错误的时间,而不是为了阻挠坏人。

出于类似的原因,最好不要通过浏览器进行测试。使用 Fiddler 构建请求以命中您想要检查的验证点。这样所有客户端验证都将被绕过,您将像攻击者一样查看服务器。
最后,请记住,具有100%完美验证的页面不一定安全。例如,如果您的验证是完美的,但您的身份验证很差,则某人可以向其发送“有效”代码,该代码将与更经典的 SQL 注入或 XSS 代码一样恶劣,甚至更加恶劣。这涉及到其他问题,除了在此讨论的验证之外,还有其他问题需要考虑。

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