【数据库】数据库入门(十一): 数据库安全(Database S
主要目标
当我们谈及数据库安全的时候,主要是希望实现三个目标:
-
机密性(Confidentiality):数据只能展示给那些获得权限允许访问的用户对象。
- 例如,由存取控制机制执行
-
完整性(Integrity):数据只能被拥有修改权限的用户对象修改。
- 例如,由模式上指定的访问控制机制和完整性约束实施
-
可用性(Availability):如果某个用户对象允许访问或修改对象,那么他应当能够这么做。
- 例如,由恢复和并发控制机制强制执行
在实现数据库安全的实践中,可能还会采用其他的服务,例如:
- 加密(Encryption):在跨系统传输和存储在辅助存储器上时保护数据。
- 查询身份验证(Query authentication):通过使用签名机制和数据结构来确保查询结果是正确的。
数据库安全提供的保护通常针对两种情况:
- 禁止没有数据库访问权限的用户进行任何访问;
- 阻止具有数据库访问权限的用户对数据库执行不需要执行的操作。
数据库安全漏洞的威胁
数据库潜在的安全漏洞,如果成功,将对数据库产生一定的影响。主要有以下几个方面,与数据库安全的主要目标对应:
- 机密性缺失(Loss of confidentiality):数据不应该被那些没有合法访问权限的人访问。
- 完整性缺失(Loss of integrity):不应通过有意或无意的行为。
- 可用性缺失(Loss of availability):数据应该对那些拥有合法访问权限的人保持可访问性。
控制措施
-
访问控制(Access control)
- 限制对数据库系统的访问
- 例如,用户帐户和密码
-
推理控制(Inference control)
- 确保用户未被授权访问的数据不能从统计或汇总数据中推断出来
- 例如,知道某个部门的平均工资,但不知道某个特定人员的工资
-
流控制(Flow control)
- 防止数据流入未经授权的用户
- 例如,避免秘密通道
-
数据加密(Data encryption)
- 在储存和传送过程中保护敏感资料
- 例如密码和信用卡资料。
访问控制(Access Control)
访问控制是指控制对数据库中资源的访问的任何方法,可以将其视为身份验证(authentication)和授权(authorization)以及其他措施(如基于ip的限制)的组合
-
身份验证(Authentication)
- 一个系统识别用户的过程(谁是用户?该用户是本人吗?)
- 以用户名称、密码、智能卡、密码、指纹扫描等方式识别。
-
身份授权(Authorization)
- 一个系统确定已通过身份验证的用户对安全资源的访问级别的过程。
- (该用户是否授权访问或修改数据表?)
访问控制的三种典型机制:
-
自主存取控制(DAC:Discretionary access control)
- 基于访问特权的概念,为用户提供这样的特权。
- SQL 支持 DAC;大多数商业 DBMS 也支持 DAC 。
-
强制存取控制(MAC:Mandatory access control)
- 基于无法由单个用户更改的系统范围策略。
- SQL 不支持 MAC,但是一些 DBMS 支持 MAC 。
-
基于角色的访问控制(RBAC:Role-based access control)
- 基于用户角色(可以与DAC和MAC一起使用)。
- 角色上的 SQL 支持特权;许多 DBMS 支持 RBAC 。
自主存取控制(DAC:Discretionary access control)
之所以称为自主存取,是因为它允许主体自行授予其他主体访问该主体对象的特权。 DAC 基于主体的特权管理主体(用户、账户、角色等)查阅客体(关系表、视图等)的权限。
SQL 通过授予(GRANT)和撤销(REVOKE)两条命令支持 DAC。
- GRANT:授予用户特权;
- REVOKE:取消用户的特权。
GRANT
基本语法:
GRANT privileges ON object TO users [WITH GRANT OPTION]
这里的 privileges 包括 select、insert、update、references 等操作关键字。
给几个例子:
GRANT SELECT ON Supplier TO Jerry;
GRANT INSERT, DELETE ON Supplier TO Tom;
GRANT UPDATE (rating) ON Supplier TO Tom;
GRANT REFERENCES (no) ON RatingStandard TO Bob;
视图(Views)
视图为自由授权提供了重要的机制。
首先,创建视图的语法为:
CREATE VIEW view name AS
SELECT attribute list
FROM table list
[WHERE condition]
[GROUP BY attribute list [HAVING group condition]]
[ORDER BY attribute list];
创建视图需要对视图定义中涉及的所有关系使用 SELECT 特权。也就是说,用户需要拥有 SELECT 特权,才能使用 SELECT 获取目标的关系内容创建视图。使用视图可以自由构建想要公开给其他对象的关系视图,从而保护其他数据不被他人访问。
REVOKE
基本语法:
REVOKE [GRANT OPTION FOR] privileges ON object FROM users
给几个例子:
REVOKE INSERT, DELETE ON Supplier FROM Peter;
GRANT SELECT ON Supplier TO Bob;
REVOKE SELECT ON Supplier FROM Bob;
权限委托与撤回
基于上述的 GRANT 和 REVOKE 命令,在实践中,我们可以迭代地给其他用户授予或者撤回权限。这时候就需要用到语法中 GRANT OPTION 的这部分关键字了。比如:
GRANT SELECT ON Supplier TO Bob WITH GRANT OPTION;
在执行移除 REVOKE 命令时,同样可以加上可选的关键字:
- CASCADE:从指定用户撤消特权,同时也会撤消从该用户收到特权的所有用户的特权。
- RESTRICT:仅从指定用户撤消特权。
如果用户从多个源接收到某个特权,并且只有在所有源都取消该特权之后,该用户才会失去该特权。比如:
GRANT SELECT ON Supplier TO Bob WITH GRANT OPTION; (by Tom)
GRANT SELECT ON Supplier TO Jerry; (by Tom)
GRANT SELECT ON Supplier TO Jerry WITH GRANT OPTION; (by Bob)
REVOKE SELECT ON Supplier FROM Bob CASCADE; (by Tom)
最后一句由 Tom 运行的命令,首先撤除了他前面授予 Bob 的 SELECT 权限,由于 CASCADE 关键字的存在,接着撤回了 Bob 授予 Jerry 的 SELECT 权限,但 Jerry 仍然拥有 Tom 在第二条命令授予的 SELECT 权限,所以他并没有失去该特权。
在实践中,有些 DBMS 和 SQL 存在用于约束特权传播的技术,通常的思路有两种:
- 限制水平传播:限制一个帐户可以通过 GRANT OPTION 最多向其他 n 个帐户授予特权。
- 限制垂直传播:限制特权授予的深度。
强制存取控制(MAC:Mandatory access control)
根据对象中包含信息的敏感性和主体对这种敏感性信息访问的正式授权来限制对对象的访问。
Bell-LaPadula模型:根据信息的敏感性(例如,安全级别)可以分为几个级别:最高机密(TS)、机密(S)、机密(C)、非机密(U)。其中
TS ≥ S ≥ C ≥ U
该模型规定了两条规则:
- (Read down)主体 X 可以读取客体 Y 仅当 X 的权限大于或等于 Y 的权限级别。
- (Write up)主体 X 可以写入客体 Y 仅当 X 的权限小于或等于 Y 的权限级别。
模型的主要思想在于,防止高级对象中的信息流向低级主题。
可以将安全级别当做是数据库关系表里的一个属性,只有当用户拥有高于或等于相应安全级别时,才能访问该组数据。比如:
id | name | city | rating | security class |
---|---|---|---|---|
1 | s1 | Paris | 4 | secret(S) |
2 | s2 | Canberra | 5 | confidential(C) |
- Bob 具有 C 权限,只能访问第二个元组。
- Peter 具有 S 权限,可以访问两个元组。
基于角色的访问控制(RBAC:Role-based access control)
访问权限按角色分组,资源的使用仅限于分配给特定角色的个人。
SQL 注入
SQL 注入通常被认为是一种针对 web 应用程序的攻击,被开放web应用程序安全项目评为2007年和2010年十大web应用程序漏洞之一。SQL 注入常用于攻击任意形态的数据库。
一个 web 应用通常会在以下场景访问数据库:
- 连接数据库;
- 向数据库发送SQL语句和数据(SQL注入!)
- 从数据库中获取结果并显示数据;
- 关闭连接。
SQL 注入的形式,通常是黑客通过 web 应用注入一个字符串,用于改变 SQL 语句,使之为他们所用。可能会有以下的方式危害到数据库:
- 改变数据库的内容;
- 从数据库中获取敏感数据,比如信用卡信息或者密码;
- 执行系统级别的命令,导致系统拒绝服务申请;
- 。。。。。。
保护技术
SQL 注入攻击可以通过下面的技术进行防御:
- 防火墙(Firewall):根据预先确定的安全规则,监控进出的网络流量;
- 入侵检测系统(IDS:Intrusion detection system):监视网络或系统是否有恶意活动或违反策略;
- 验证(Authentication):系统识别用户的过程。
可以通过将某些规则应用于所有 web 可访问的过程和函数来实现对 SQL 注入攻击的保护。
- 参数化查询(Parameterized queries):用于通过防止 SQL 注入来提高安全性(最佳解决方案)。
- 语句是预先定义好的,用于通过解析和编译,其中的问号 ? 用作实际参数的位置容器。
- 实际参数被传递到准备好的语句中执行。
- 主要思想就是,将控制与数据两部分分离。
PreparedStatement stmt=conn.prepareStatement("SELECT * FROM users WHERE name=? and password=?");
stmt.setString(1, user name);
stmt.setString(2, user passwd);
- 输入验证(Input validation):用于从输入字符串中删除或转义字符
- 黑名单(Blacklisting):输入字符串中的引号、分号等。然而,如果忘记将一种类型的危险人物列入黑名单,它可能会导致一次成功的攻击。
- 白名单(Whitelisting):显式地测试给定的输入是否在一组定义良好的已知安全的值中。
- 转义(Escaping):将危险的输入字符转换为经过消毒的输入字符串
"SELECT * FROM users WHERE name = `" + escape(user name) + "' and password= `" +escape(user passwd) +"'"