当我们谈及数据库安全的时候,主要是希望实现三个目标:
在实现数据库安全的实践中,可能还会采用其他的服务,例如:
数据库安全提供的保护通常针对两种情况:
数据库潜在的安全漏洞,如果成功,将对数据库产生一定的影响。主要有以下几个方面,与数据库安全的主要目标对应:
访问控制是指控制对数据库中资源的访问的任何方法,可以将其视为身份验证(authentication)和授权(authorization)以及其他措施(如基于ip的限制)的组合
以用户名称、密码、智能卡、密码、指纹扫描等方式识别。
身份授权(Authorization)
一个系统确定已通过身份验证的用户对安全资源的访问级别的过程。
(该用户是否授权访问或修改数据表?)
访问控制的三种典型机制:
之所以称为自主存取,是因为它允许主体自行授予其他主体访问该主体对象的特权。 DAC 基于主体的特权管理主体(用户、账户、角色等)查阅客体(关系表、视图等)的权限。
SQL 通过授予(GRANT)和撤销(REVOKE)两条命令支持 DAC。
基本语法:
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;
视图为自由授权提供了重要的机制。
首先,创建视图的语法为:
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 [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 命令时,同样可以加上可选的关键字:
如果用户从多个源接收到某个特权,并且只有在所有源都取消该特权之后,该用户才会失去该特权。比如:
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 存在用于约束特权传播的技术,通常的思路有两种:
根据对象中包含信息的敏感性和主体对这种敏感性信息访问的正式授权来限制对对象的访问。
Bell-LaPadula模型:根据信息的敏感性(例如,安全级别)可以分为几个级别:最高机密(TS)、机密(S)、机密(C)、非机密(U)。其中
TS ≥ S ≥ C ≥ U
该模型规定了两条规则:
模型的主要思想在于,防止高级对象中的信息流向低级主题。
可以将安全级别当做是数据库关系表里的一个属性,只有当用户拥有高于或等于相应安全级别时,才能访问该组数据。比如:
id | name | city | rating | security class |
1 | s1 | Paris | 4 | secret(S) |
2 | s2 | Canberra | 5 | confidential(C) |
访问权限按角色分组,资源的使用仅限于分配给特定角色的个人。
SQL 注入通常被认为是一种针对 web 应用程序的攻击,被开放web应用程序安全项目评为2007年和2010年十大web应用程序漏洞之一。SQL 注入常用于攻击任意形态的数据库。
一个 web 应用通常会在以下场景访问数据库:
SQL 注入的形式,通常是黑客通过 web 应用注入一个字符串,用于改变 SQL 语句,使之为他们所用。可能会有以下的方式危害到数据库:
SQL 注入攻击可以通过下面的技术进行防御:
可以通过将某些规则应用于所有 web 可访问的过程和函数来实现对 SQL 注入攻击的保护。
PreparedStatement stmt=conn.prepareStatement(
"SELECT * FROM users WHERE name=? and password=?");
stmt.setString(1, user name);
stmt.setString(2, user passwd);
"SELECT * FROM users WHERE name = `" + escape(user name) +
"' and password= `" +escape(user passwd) +"'"