第一道防线是由 ASP.NET(特别是 RegularExpressionValidator 类和 RequiredFieldValidator 类)提供的有效性验证控制,可确保提供了所需的所有输入,且均为有效数据。只允许使用用于提供所需用户操作的字符,在本例中,字符范围很有限。例如,某些字段只允许输入“[ ',.0-9a-zA-Z_]*”,即空格、单引号、逗号、句号、字母和数字。其他可用于向 Web 站点发送恶意脚本的字符被禁止使用。
除文本框以外,本应用程序还通过“查询字符串”接受某些输入,查询字符串是动态 URL 的一部分,包含用于生成页面的参数。通过 System.Text.RegularExpressions.Regex 类提供的功能,用正则表达式对数据进行验证,如下所示:
Regex isNumber = new Regex("^[0-9]+$");
if(isNumber.Match(inputData) ) {
// 使用它
}
else {
// 丢弃它
}
正则表达式是用于匹配文本模式的字符和语法元素集合。在 OpenHack 应用程序中,它们用于确保查询字符串内容是正确且无恶意的。
此应用程序中的所有数据访问均通过参数化存储过程完成,这些存储过程是使用 T-SQL 语言开发的,并且根据定义在数据库内运行。将与数据库的交互限制到存储过程,这通常是一个最佳方案。如果不存在存储过程,则 SQL 查询必须由 Web 应用程序动态构造。如果 Web 层遭到破坏,攻击者就可以向数据库查询中插入恶意命令,以检索、更改或删除数据库中存储的数据。使用存储过程,Web 应用程序与数据库的交互操作仅限于通过存储过程发送的几个特定的严格类型参数。每当开发人员使用 .NET Framework 调用存储过程时,系统都会对发送到此存储过程的参数进行检查,以确保它们是存储过程可接受的类型(如整数、8 个字符的字符串等)。这是 Web 层有效性验证上的又一个保护层,可确保所有输入数据格式正确,而且不能自行构造为可操作的 SQL 语句。
任何数据在返回给用户前均采用 HTML 编码。这只需使用 System.Web.HttpServerUtility 类中的 HtmlEncode 方法即可实现,如下所示。
SomeLabel.Text = Server.HtmlEncode(username);
HTML 编码有助于防止跨站点的脚本攻击。攻击者一旦破坏了数据库,便可向记录中输入脚本,此脚本随后返回给用户并在浏览器中执行。通过 HTML 编码,大多数脚本命令都自动转换为无害文本。
存储机密信息
安全地存储机密信息(如提供数据库登录信息的数据库连接字符串)很重要,这样可以防止攻击者访问并使用这些机密信息来读取、操作数据或重新配置解决方案。由于本解决方案使用了集成的 Windows 身份验证来访问数据库,因此连接字符串的价值对于攻击者来说已经显著降低,这是因为连接字符串只包含服务器的位置和数据库名称,而不包括特定的凭据(如密码)。