DB 连接是重要且有限的资源,连接应该尽可能晚地打开,并尽可能早地关闭。连接的使用应该尽量简短,一个连接最长持续时间不应该超过一个方法调用。不应该在方法之间传递连接,这种做法不仅带来性能问题并且会限制程序的可伸缩性,而且会产生安全问题。
.NET 2.0 引入了保护配置,作为 ASP.NET 应用程序所使用的连接字符串的一种存储加密机制。它引入了 connectionStrings 配置元素,指定了一个数据库字符串集合,在之前的版本中,连接字符串存储在 appSettings 元素中。
连接字符串的 Persist Security Info 属性指定了数据源是否可以保存像用户验证信息这样的敏感信息。它的值应该保持为默认值 false 。如果它的值是 true ,就可以通过查询连接获取包括密码在内的连接信息,这就允许未得到信任方在 Connection 被传递或保存到磁盘时可以访问敏感信息。只有在传递像 Connection 或 DataAdapter 这样的连接对象时才会出现这个问题。像 DataSet 和 DataTable 这样的断开连接对象不会存储数据源信息。
注意,数据源对象第一次初始化时,不管该属性设置如何,都可以从它那里获取敏感信息。因此,要避免传递未初始化的数据源对象。还有,ODBC 的提供程序并不支持这一属性,但他的行为相对于 Persist Security Info 为 false 并且不能被修改。
总的来说,我们要注意:
- 总是用最小所需的许可来配置预定义的账户;
- 尽可能使用集成安全;
- 总是对存储的信任进行加密,并精心控制对相关关联的密钥访问;
- 从不使用 Sa 或其他任何管理员账户;
- 从不使用空密码或其他安全性很弱的密码。
我们还需要在最佳位置存储连接字符串,以提高应用程序的可维护性,简化将来对连接字符串的修改。
- 使用配置文件
访问配置文件需要添加对 System.Configuration 程序集的引用。
代码形如:
string connStr=ConfigurationManager.ConnectionStrings[ "MyConn" ].ConnectionString; SqlConnection conn= new SqlConnection(connStr); |
配置文件可以帮助部署,但是它本质上是不安全的,可以通过文件系统访问。为此可以对配置文件中的连接和其它敏感信息进行加密并确保把 NTFS 文件权限设置为限制访问这个文件。
- 硬编码
代码形如:
SqlConnectionStringBuilder scsb= new SqlConnectionStringBuilder(); scsb.DataSource= "(local)" ; scsb.Add( "Initial Catalog" , "AdventureWorks" ); scsb[“Integrated Security"]= true ; SqlConnection conn= new SqlConnection(scsb.ConnectionString); |
对连接字符串采用硬编码方式是不受推荐的。几乎在所有情况下,外部存储方案都是优选的,这是因为他们更安全灵活且易于配置。
- 统一数据连接文件
OLEDB 数据提供程序支持在连接字符串中使用 UDL 文件名。UDL 文件是位于应用程序外部的资源,在一个单独的文件中封装了连接属性。它必须用 NTFS 安全进行保护,以防止连接信息被暴露或更改。SQL Server 数据提供程序不支持在连接字符串中使用 UDL 文件。UDL 文件并不进行加密,使用加密并不能提高它的安全性。NTFS 目录和文件加密可以保证 UDL 文件的安全。因此,即使获得了对该文件的未认证访问,仍然需要对这个文件进行加密的用户ID和密码才能访问它的内容。
- Windows 注册表
可以把连接字符串存储在 Windows 注册表中,作为 HKEY_LOCAL_MACHINESOFTWARE 的一个子键。可以在注册表中对这些设置进行加密,并限制对这个子键的访问。.NET 在 Microsoft.Win32 命名空间中所提供的 Registry 和 RegistryKey 类支持代码访问注册表。由于部署原因,不推荐使用这种方式保存连接信息。
- 自定义文件
自定义文件是专门用于存储应用程序设置的任何文件,这种方式会增加额外的编码,需要显式地处理并发和安全等问题,并且没有特别的优点,所以不推荐使用。