实现代码安全

 

1.   验证应用程序的输入

1.1. 用户输入验证的类型

恶意用户可以利用输入来攻击一个应用,原因在于可以通过此手段来暴露应用的一些实现细节或者使得应用生成一些恶意数据。另外,攻击者还可以在应用中执行恶意脚本和访问受限资源。所以,如果不验证用户输入对应用是有害的。我们可以对用户输入进行客户端或者服务器端验证。这些验证分为——Client-side validation(第一道安全防线,在数据发送到server前进行验证);Server-side validation(在用户的代码使用数据前进行验证);ASP.NET validation(包括很多验证控件)。

 

1.2. ASP.NET 验证控件

对于ASP.NET应用可以使用下面的这些验证控件对用户输入进行验证。

l         RequiredFieldValidator

l         RangeValidator

l         RegularExpressionValidator

l         CompareValidator

l         CustomValidator

比如可以使用RangeValidator控件来验证输入是否在一定的范围内。可以对数字和日期进行范围验证。

1.3. 正则表达式

正则表达式就是一串符号字符,这些符号定义了需要被发现和替换的模式。可以使用正则表式来限制有效的字符,去处不期望的字符,还可以执行长度和格式检查。

1.4. 使用.NET Framework提供的正则表达式功能进行验证

l         Using regular expressions in ASP.NET

l         The RegularExpressionValid-ator control

l         The Regex class——System.Text.RegularExpressions.Regex

 

2.   验证外部组件的输入

我们可能整合一些预构建的组件,比如ActiveX控件,自定义控件,COM组件,.Net的程序集。然而,整合这些预构建的组件可能引入重大的安全威胁和风险。这些组件可能是从互联网上下载的,甚至含有有意的安全漏洞,比如后门,病毒和木马。可以使用适当的输入验证方法来降低威胁。在输入进入到系统之前,必须对这些组件的任何输入进行验证。

测试每个组件的安全弱点——错误处理,类型安全和内容使用。可以使用正则表示式来验证输入。

 

2.1. 关于减小输入攻击威胁的指导原则

2.1.1.    假定任何输入都是恶意的

任何输入都是恶意的,除非有其它证明。防止恶意输入被继续处理;检查所有进入系统的输入,如果它超越了信任边界。

2.1.2.    集中验证机制

建立一个公共类库来做验证的工作。将输入验证策略作为应用程序设计的一个核心元素。这样便于维护。

2.1.3.    约束, 抛弃和净化输入

l         Constrain input——使用过滤器,来对类型,长度,格式和范围进行检查。

l         Validate data for type, length, format, and range

l         Reject known bad input——这适合于已经部署的应用,且了解会有哪些安全威胁的情况下。

l         Sanitize input——使得有潜在危险的数据变得安全。

3.   安全异常

安全异常表明有.Net代码中的安全错误被探测到。如果没有很好地处理这样的安全异常,它很可能弹出一个窗口给攻击者,或者它导致应用崩溃。

3.1. 概述

一个安全异常就是一个当CLR遇到安全错误的时候抛出的异常对象。它表明.Net代码执行了一个其没有权限的操作。安全错误的种类——(1)代码访问许可,它继承System.Security.CodeAccessPermission抽象类。这个许可代表访问受保护的资源或者受保护操作的能力。(2)身份许可,它继承了CodeAccessPermission。它表明它拥有支持特定身份的证明。(3)基于角色的安全许可,实现System.Security.IPermissionSystem.Security.ISecurityEncodable接口。这些许可提供了一种去发现是否一个用户有特定的身份或者是一个特定角色的成员。

3.2. 关于错误处理的指导

l         知道如何使用trycatch块进行异常处理。

l         将会产生异常的代码放在tryfinally块中。

l         将异常在catch块中进行组织。

l         对于经常发生的错误,返回空。

l         不暴露过多的信息给用户。

l         安全地停止运转。即使应用因错误而停止了,其结果也是安全的。

3.3. 关于创建自定义异常类的指导

l         命名时以Exception作为后缀。

l         为远程执行的异常代码提供元数据。

l         使用至少三个构造函数。

l         使用预定义的异常类型。

l         自定义异常继承自ApplicationException类。

l         为每个异常提供本地化描述。

 

4.   评估规范化问题

介绍在基于web的应用和基于无文件的资源中会遇到的通常的规范性问题。

4.1. WindowsWeb-Based应用中的规范化问题

标准化的数据就是指它的最标准和简单的格式。标准化就是指将数据转换为标准格式的过程。文件路径和URL是最容易受标准化问题影响的,而且很多众所周知的问题就是规范化bug的结果。

l         Using long file names——使用长文件名。FAT只支持最长8个字符的文件名,而FAT32NTFS则支持255Unicode字符的文件名,为了向后兼容,FAT32NTFS允许DOS16Windows的应用使用通过自动产生的8.3格式的文件名访问相同的文件。比如NTFS分区的文件MyLongFilename.txt,其8.3格式为MyLong~1.txt。而恶意用户可以通过输入短文件名来突破验证长文件名的应用的安全。

l         Using NTFS alternate data streams——使用NTFS预备的数据流。使用.asp::$DATA方式请求asp文件时,IIS不能确定请求的是NTFS的数据流,而返回源代码给请求者。

l         Using trailing characters——使用拖尾符。

l         Using the \\?\ format ——使用\\?\格式。通过添加“\\?\”到文件名的前面,Unicode版本的文件操作函数允许32000个字符的文件扩展名。好的做法是使用System.IO.Path.GetFullPath方法来得到路径名。

l         Using parent paths——使用上级路径。如果使用了上级路径,则恶意者可以了解到系统的文件路径结构,给其机会操作系统中其它本来无权操作的文件——给恶意者提供机会破坏系统。

l         Using relative file names——使用相对文件名。如果只给出文件名,而没有给出具体位置,则可能造成应用加载错误的文件——应用不能确定是从当前路径加载还是从环境变量定义的路径加载文件。

l         Using device names and reserved names——使用驱动器名和保留名。恶意者通过输入驱动器名或者保留名,可以造成系统错误。

 

4.2. 关于防止 Windows Web-Based 应用中的规范化问题的指导

l         Avoid making decisions based on file names——避免使用文件名来做决定。使用文件系统,操作系统和ACL来验证文件名。

l         Restrict valid file names——限定有效的文件名。(1)绝对路径的文件;(2)必须是磁盘分区中的文件;(3)文件名不超过32个字符;(4)限定文件扩展名。比如.txtdoc

l         Stop the 8.3 generation of file names——停止使用8.3式生成的文件名。

l         Use full paths for file names——不要从path环境变量制定的路径加载文件,因为恶意者可能修改此变量的值以突破应用的安全。

l         Attempt to canonicalize file names——使用Win32函数规范化文件名。

4.3. Server User 名称中的规范化问题

虽然大多数规范性安全弱点和文件名相关,但其中一些也和多个名字代表同一个资源有关,比如服务器名和用户名。

服务器名——如果需要以服务器名来做决定,则应该选择合适的规范的服务器名,拒绝其它不符合此规范的任何名字。

用户名——接受SAMDOMAIN\username)格式的用户名,而拒绝其它格式的用户名。

 

posted @ 2005-07-26 12:33  风满袖  阅读(2576)  评论(9编辑  收藏  举报