SQL Server 安全性最佳实践
适用于: SQL Server Azure SQL 数据库 Azure SQL 托管实例
本文提供了有关实现 SQL Server 安全性的最佳实践和指南的信息。 若要全面了解 SQL Server 安全功能,请参阅保护 SQL Server。
有关具体产品的安全最佳实践,请参阅 Azure SQL 数据库和 SQL 托管实例和 Azure VM 上的 SQL Server。
概述
分层安全方法通过利用针对不同安全作用域的多个安全功能提供深层防御解决方案。 借助在 SQL Server 2016 中推出并在后续版本中进行了改进的安全功能,可以应对安全威胁,并提供可靠的数据库应用程序。
Azure 遵守多个行业法规和标准,使用户能够使用虚拟机中运行的 SQL Server 生成符合规定的解决方案。 有关 Azure 合规性的信息,请参阅 Azure 信任中心。
列级别保护
组织通常需要在列级别保护数据,因为与客户、员工、商业秘密、产品数据、医疗保健、财务和其他敏感数据相关的数据通常存储在 SQL Server 数据库中。 敏感列通常包括身份证明/社保编号、移动电话号码、名字、姓氏、财务帐户标识,以及可以视为个人数据的任何其他数据。
本部分所述的方法和功能将以最小的开销在列级别提升保护级别,而无需对应用程序代码进行大量更改。
使用 Always Encrypted 对静态数据和传输中的数据进行加密。 仅在应用程序客户端级别对加密数据进行解密。 尽可能使用随机加密而不是确定性加密。 具有安全 Enclave 的 Always Encrypted 可以在随机加密方案中提高比较操作(如 BETWEEN、IN、LIKE、DISTINCT、Join 等)的性能。
当 Always Encrypted 不可用时,使用动态数据掩码 (DDM) 在列级别对数据进行模糊处理。 动态数据掩码 (DDM) 与 Always Encrypted 不兼容。 尽可能使用 Always Encrypted 而不是动态数据掩码。
还可以在列级别将权限授予表、视图或表值函数。 考虑以下事项:- 只能授予对列的 SELECT
、REFERENCES
及 UPDATE
权限。
- 表级 DENY
并不优先于列级 GRANT
。
行级别保护
行级别安全性 (RLS) 使用户能够使用用户执行上下文来控制对数据库表中的行的访问。 RLS 可确保用户只能看到与其相关的记录。 这样就无需对应用程序进行重大更改,从而提高了应用程序“记录级别”的安全性。
业务逻辑封装在由用于打开和关闭 RLS 功能的安全策略所控制的表值函数中。 该安全策略还控制绑定到 RLS 所操作的表的 FILTER
和 BLOCK
谓词。 使用行级别安全性 (RLS) 限制向发出调用的用户返回的记录。 对于通过应用程序用户共享同一个 SQL Server 用户帐户的中间层应用程序连接到数据库的用户,使用 SESSION_CONTEXT (T-SQL)。 为了获得最佳的性能和可管理性,请遵循行级别安全性最佳实践。
提示
将行级别安全性 (RLS) 与 Always Encrypted 或动态数据掩码 (DDM) 结合使用,以最大程度地提高组织的安全状况。
文件加密
透明数据加密 (TDE) 通过为数据库文件提供静态加密,在文件级别保护数据。 透明数据加密 (TDE) 可确保在不使用正确的证书解密数据库文件的情况下无法附加和读取数据库文件、备份文件和 tempdb
文件。 如果没有透明数据加密 (TDE),攻击者可能会带走物理介质(驱动器或备份磁带)并还原或附加数据库以读取内容。 支持透明数据加密 (TDE) 是为了与 SQL Server 中的所有其他安全功能配合工作。 透明数据加密 (TDE) 可对数据和日志文件执行实时 I/O 加密和解密。 TDE 加密利用存储在用户数据库中的数据库加密密钥 (DEK)。 还可以使用受 master
数据库的数据库主密钥保护的证书来保护数据库加密密钥。
使用 TDE 保护静态数据、备份和 tempdb
。
审核和报告
若要审核 SQL Server,请在服务器级别或数据库级别创建审核策略。 服务器策略将应用到服务器上的所有现有数据库和新建数据库。 为简单起见,请启用服务器级审核并允许数据库级审核继承所有数据库的服务器级属性。
审核包含应用了安全措施的敏感数据的表和列。 如果表或列非常重要,需要使用安全功能进行保护,则应将其视为重要,需要进行审核。 尤其重要的是,对于包含敏感信息,但是由于某种应用程序或体系结构限制而不可能应用所需的安全措施的表,应进行审核和定期检查。
标识和身份验证
SQL Server 支持两种身份验证模式:Windows 身份验证模式和“SQL Server 和 Windows 身份验证模式”(混合模式)。
登录名独立于数据库用户。 必须将登录名或 Windows 组映射单独到数据库用户或角色。 接下来,向用户、服务器角色和/或数据库角色授予访问数据库对象的权限。
SQL Server 支持以下三种登录类型:
- 本地 Windows 用户帐户或 Active Directory 域帐户 - SQL Server 依赖 Windows 对 Windows 用户帐户进行身份验证。
- Windows 组 - 向 Windows 组授予访问权限会向作为组成员的所有 Windows 用户登录名授予访问权限。 将用户从组中删除将删除用户来自组的权限。 组成员身份是首选策略。
- SQL Server 登录名 - SQL Server 将用户名和密码哈希存储在
master
数据库中。 - 包含的数据库用户在数据库级别对 SQL Server 连接进行身份验证。 包含的数据库是独立于其他数据库以及托管数据库的 SQL Server 实例(以及
master
数据库)的一种数据库。 SQL Server 支持包含的数据库用户进行 Windows 和 SQL Server 身份验证。
以下建议和最佳实践可帮助保护你的标识和身份验证方法:
使用最小权限基于角色的安全性策略来改进安全管理。
- 将 Active Directory 用户放入 AD 组中是标准做法,AD 组应存在于 SQL Server 角色中,并且应向 SQL Server 角色授予应用程序所需的最小权限。
在 Azure 中,通过使用基于角色的访问 (RBAC) 控件来利用最小权限安全性
尽可能选择 Active Directory 而不是 SQL Server 身份验证,特别是选择 Active Directory,而不是在应用程序或数据库级别存储安全性。
- 如果用户离开公司,可以很轻松地禁用帐户。
- 当用户变更角色或离开组织时,还可以轻松将用户从组中删除。 组安全性被视为最佳实践。
对具有计算机级别访问权限的帐户使用多重身份验证,包括使用 RDP 登录到计算机的帐户。 这有助于防止凭据被盗或泄漏,因为基于密码的单因素身份验证是一种较弱的身份验证形式,其中的凭据存在被泄露或者被错误丢弃的风险。
需要使用强且复杂的密码,这种密码应不容易被猜到,也不要用于任何其他帐户或用途。 定期更新密码并强制实施 Active Directory 策略。
组托管服务帐户 (gMSA) 提供自动密码管理、简化的服务主体名称 (SPN) 管理并将管理权委托给其他管理员。
- 使用 gMSA 时,Windows 操作系统管理帐户的密码,而不是依赖管理员来管理密码。
- gMSA 会自动更新帐户密码,而无需重新启动服务。
- gMSA 降低了管理面,改进了职责分离。
最大程度地减少授予 DBA AD 帐户的权限;请考虑职责隔离以限制对虚拟机的访问、登录操作系统的能力、修改错误和审核日志的能力,以及安装应用程序和/或功能的能力。
请考虑从 sysadmin 角色中删除 DBA 帐户,并向 DBA 帐户授予 CONTROL SERVER,而不是使其成为 sysadmin 角色的成员。 系统管理员角色不接受
DENY
,而 CONTROL SERVER 接受。
数据世系和数据完整性
将数据更改的历史记录保留一段时间对于应对数据的意外更改非常有利。 它还可用于应用程序更改审核,并且当错误的参与者引入了未经授权的数据更改时,可以恢复数据元素。
- 利用临时表将记录版本保留一段时间,并在记录的生命周期内查看数据,以提供应用程序数据的历史视图。
- 临时表可用于提供任意时间点的当前表版本。
安全评估工具和评估
下面的配置和评估工具可保证外围应用安全、标识数据安全机会,并在实例级别提供 SQL Server 环境安全性的最佳实践评估。
- 外围应用配置 - 建议仅启用环境所需的功能,以便最大限度地减少可能受到恶意用户攻击的功能的数量。
- SQL Server (SSMS) 的漏洞评估是 SSMS v17.4+ 中的一个工具,可帮助发现、跟踪和修正潜在的数据库漏洞。 漏洞评估是一个非常有用的工具,可用于提高数据库的安全性,并在数据库级别在每个数据库中执行。
- SQL 数据发现和分类 (SSMS) - 通常,DBA 管理着服务器和数据库,而不知道数据库中包含的数据的敏感性。 数据发现和分类添加了在敏感度级别发现、分类、标记和报告数据的功能。 从 SSMS 17.5 开始,支持数据发现和分类。
常见 SQL 威胁
这有助于了解危及 SQL Server 的一些常见威胁:
- SQL 注入 - SQL 注入攻击会将恶意代码插入字符串中,这些字符串会传递给 SQL Server 实例来完成执行操作。
- 注入过程的工作原理是终止文本字符串,然后追加一个新的命令。 由于插入的命令可能在执行前追加其他字符串,因此攻击者将用批注标记
--
来终止注入的字符串。 - SQL Server 将执行接收到的任何语法上有效的查询。
- 注入过程的工作原理是终止文本字符串,然后追加一个新的命令。 由于插入的命令可能在执行前追加其他字符串,因此攻击者将用批注标记
- 请注意旁道攻击、恶意软件和其他威胁。
SQL 注入风险
若要最大程度地降低 SQL 注入风险,请考虑以下事项:
- 检查构成 SQL 语句的任何 SQL 进程是否存在注入漏洞。
- 以参数化方式构造动态生成的 SQL 语句。
- 开发人员和安全管理员应检查调用
EXECUTE
、EXEC
或sp_executesql
的所有代码。 - 禁止以下输入字符:
;
:查询分隔符'
:字符数据字符串分隔符--
:单行注释分隔符。/* ... */
:注释分隔符。xp_
:目录扩展存储过程,例如xp_cmdshell
。- 不建议在任何 SQL Server 环境中使用
xp_cmdshell
。 请改为使用 SQLCLR 或查找其他替代方法,因为可能会导致xp_cmdshell
风险。
- 不建议在任何 SQL Server 环境中使用
- 始终验证用户输入并清理错误输出,防止溢出并暴露给攻击者。
旁道风险
若要最大程度地降低旁道攻击的风险,请考虑以下事项:
- 确保应用最新的应用程序和操作系统修补程序。
- 对于混合工作负荷,请确保为本地的任何硬件应用最新的固件修补程序。
- 在 Azure 中,对于高度敏感的应用程序和工作负荷,可以通过隔离的虚拟机、专用主机或利用机密计算虚拟机(例如 DC 系列和使用第三代 AMD EPYC 处理器的虚拟机)添加对旁道攻击的额外保护。
基础设施威胁
请考虑以下常见的基础设施威胁:
- 暴力访问 - 攻击者尝试在不同帐户上使用多个密码进行身份验证,直到找到正确的密码。
- 密码破解/密码喷射 - 攻击者针对所有已知用户帐户尝试一个精心设计的密码(对多个帐户使用一个密码)。 如果初次密码喷射失败,他们会重试,使用另一个精心设计的密码,通常在尝试之间会等待一定时间以避开检测。
- 勒索软件攻击是一种定向攻击,使用恶意软件来加密数据和文件,阻止对重要内容的访问。 攻击者通常以加密货币的形式向受害者勒索钱财,以换取解密密钥。 大多数勒索软件感染是由包含附件的电子邮件(这些附件会试图安装勒索软件)或者托管攻击工具包的网站(这些攻击工具包会试图在 Web 浏览器和其他软件中利用漏洞来安装勒索软件)导致的。
密码风险
如果你不希望攻击者轻松猜出帐户名或密码,以下步骤将有助于降低密码被发现的风险:
- 创建一个唯一的本地管理员帐户,不要命名为 Administrator。
- 对所有帐户使用复杂的强密码。 若要深入了解如何创建强密码,请参阅创建强密码一文。
- 默认情况下,Azure 在 SQL Server 虚拟机安装期间会选择 Windows 身份验证。 因此,会禁用 SA 登录名,并由安装程序分配密码。 建议不要使用或启用 SA 登录名。 如果必须使用 SQL 登录名,请使用以下策略之一:
创建一个名称唯一且具有 sysadmin 成员资格的 SQL 帐户。 可通过在预配期间启用 SQL 身份验证,从门户执行此操作。
提示
如果预配期间未启用 SQL 身份验证,则必须手动将身份验证模式更改为 SQL Server 和 Windows 身份验证模式。 有关详细信息,请参阅更改服务器身份验证模式。
如果必须使用 SA 登录名,请在预配后启用该登录名,并分配新的强密码。
勒索软件风险
请考虑以下事项,以最大程度地降低勒索软件风险:
- 防范勒索软件的最佳策略是特别注意 RDP 和 SSH 漏洞。 此外,请考虑以下建议:
- 使用防火墙和锁定端口
- 确保应用最新的操作系统和应用程序安全更新
- 使用组托管服务帐户 (gMSA)
- 限制对虚拟机的访问
- 需要实时 (JIT) 访问和 Azure Bastion
- 通过避免在本地计算机上安装 sysinternals 和 SSMS 等工具,提高外围应用安全性
- 避免安装 Windows 功能、角色和启用不需要的服务
- 此外,应安排与公共管理员帐户分开保护的常规完整备份,以免删除数据库的副本。