出于安全原因进行 Web 应用程序输入验证的目的

Purpose of web app input validation for security reasons

我经常遇到通过输入验证来保护 Web 应用程序免受许多漏洞影响的建议,例如 SQL 注入和其他类型的注入。 它有时甚至被认为是最重要的技术。

就个人而言,我认为出于安全原因的输入验证从来都不是必需的,最好用

代替

当然,对于良好的 UX,最好在 GUI 的后面和早期捕获会产生错误的输入,但这是另一回事。

我是不是遗漏了一些东西或者是为了弥补以上两个规则的错误?

  1. 并非所有 SQL 语句都是可参数化的。例如,如果您需要使用动态标识符(而不是文字)。即使是白名单也很难,有时它需要是动态的。

  2. 在输出时转义 XSS 是个好主意。直到你忘记在你的管理仪表板上转义它,他们会窃取你所有管理员的 cookie。不要让 XSS 进入你的数据库。

是的,你大体上是正确的。

一条数据只有在"used"时才是危险的。并且只有在使用的上下文中具有特殊含义时才是危险的。

例如,<script> 只有在输出到 HTML 页面时才是危险的。

Robert'); DROP TABLE Students;-- 只是危险 when used in a database query.

通常,您希望使此数据 "safe" 尽可能晚。例如当输出为 HTML 到 HTML 页面时进行 HTML 编码,并在插入数据库时​​进行参数化。这样做的最大好处是,当稍后从这些位置检索数据时,将以其原始的、未净化的格式返回。

因此,如果您在输入字段中有值 A&B O'Leary,它将被编码为:

<input type="hidden" value="A&amp; O&#x27;Leary" />

如果将其提交给您的应用程序,您的编程框架会自动将其解码回 A&B O'Leary。与您的数据库相同:

string name = "A&B O'Leary";
string sql = "INSERT INTO Customers (Name) VALUES (@Name)";
SqlCommand command = new SqlCommand(sql);
command.Parameters.Add("@Name", name];

简单。

此外,如果您随后需要以纯文本形式向用户提供任何输出,您应该从您的数据库中检索它并将其吐出。或者在 JavaScript - you just JavaScript entity encode 中(虽然出于复杂性原因最好避免 - 我发现如果我只输出到 HTML 然后从 DOM 读取值更容易保护)。

如果您 HTML 提前对其进行了编码,那么要输出到 JavaScript/JSON 您首先必须将其转换回来,然后进行十六进制实体编码。它会变得混乱,一些开发人员会忘记他们必须先解码,你到处都会有 &s。

可以使用验证作为额外的防御措施,但它不应该是第一个停靠点。例如,如果您正在验证英国邮政编码,您可能希望将大写和小写字母数字字符列入白名单。您的应用程序将拒绝或删除任何其他字符。这可以减少 SQLi 或 XSS 在您的应用程序中发生的机会,但这种方法适用于您需要输入以包含对输出上下文具有特殊含义的字符(" '<> 等)的情况。例如,在 Stack Overflow 上,如果他们不允许此类字符,您将阻止问题和答案包含代码片段,这几乎会使网站无用。