当今大多数 Web 应用程序都需要至少采用某种基本的安全策略例如提供用口令保护的内容的网站仅具有管理员后端的网站网志和个人杂志电子商务网站企业内联网等等
构建这些类型的 Web 应用程序最常用的设计方法是将安全策略整合到 Web 应用程序的业务逻辑中即由应用程序决定某个用户是否有权访问数据库中的某个数据在这种情形下数据库的角色仅为存储数据和依请求提供数据换句话说如果 Web 应用程序命令数据库提供特定信息则数据库会直接执行该命令而不检查用户的权限
在该文中您将学习如何利用 Oracle 内置的安全特性在数据库级执行应用程序安全规则以提高应用程序的整体安全性作为附带的好处直接在数据库中实现数据访问安全不但有助于提高应用程的安全性而且有助于降低复杂性
对数据库端安全性的需求
从 Web 应用程序控制数据访问会怎么样?大多数情况下没有问题这是个不错的解决方案尤其是在涉及的数据为非任务关键或绝密的时候许多书和在线资源中都用到了该方法实际上有本很受欢迎的 PHP/MySQL 书明确反对每个应用程序创建一个以上的数据库用户帐户这是因为额外的用户或复杂的权限会因某个操作在继续前要检查更多的信息而降低 MySQL 的执行速度确实如此但是在放弃将安全性整合到数据库逻辑中的想法前可能要考虑几件事情我们来看以下示例
假设创建一个内容管理系统 (CMS)其中使用数据库来存储网站上发布的内容大部分数据是公开的允许匿名 Web 用户读取但只允许编辑更改数据使用单一数据库帐户访问和修改数据库中的记录并通过用口令保护仅管理员可以访问的页面的访问权限用 PHP 代码控制安全性
如果 Web 应用程序的公共端遭受了一个诸如公共搜索表单(即编码不够严密的表单)上的 SQL 注入的攻击则该入侵者可能能够对该公共帐户可以访问的数据库对象执行任意 SQL 语句当然就这里的情形而言执行 SELECT 语句不会造成什么大问题这是因为数据本来就是公共的但由于公共权限和管理权限使用同一数据库帐户因此入侵者还能执行 UPDATE 和 DELETE 语句甚至是从数据库中删除表
怎么才能防止该情况的发生呢?最简单的方法就是彻底限制公共数据库帐户修改数据的权限我们来看看 Oracle 是如何解决这个问题的
Oracle 安全性基本概述
Oracle 数据库为 Web 开发人员提供了控制数据访问的许多方法从管理对特定数据库对象(如表视图和过程)的访问到控制个别行或列的数据的访问很显然对 Oracle 每个安全特性或可用选项的讨论超出了本文的范围在这里我们将不涉及过多细节而仅介绍 Oracle 数据访问安全性的最基本方面
·验证和用户帐户
·权限
·角色
验证和用户帐户 与其他数据库一样请求访问 Oracle 的每个用户(数据库帐户)必须通过验证验证工作可以由数据库操作系统或网络服务来做除基本的验证(口令验证)外Oracle 还支持强验证机制如KerberosCyberSafeRADIUS等等
角色 Oracle 角色是一个权限的有名集尽管可以直接授予用户帐户权限但使用角色可以极大简化用户管理尤其是需要管理大量用户时创建易管理的小角色然后根据用户的安全级别授予用户一个或多个角色这样做的效率非常高更不用说修改权限变得如何简单了 — 只需修改角色关联的角色即可无需修改每个用户帐户
为了简化新用户创建初期的工作Oracle 自带了三个预定义的角色
·CONNECT 角色 — 该角色使用户可以连接数据库以及执行基本的操作如创建自己的表默认情况下该角色不能访问其他用户的表
·RESOURCE 角色 — RESOURCE 角色与 CONNECT 角色相似但它允许用户拥有较多的系统权限如创建触发器或存储过程
·DBA 角色 — 允许用户拥有所有系统权限
使用中的授权和权限
在本部分中我们将讨论如何使用 Oracle 的授权和权限来提高本文开头部分讨论的那个简单 CMS 示例的安全性假定提供给应用程序用户的内容存储在 WEB_CONTENT 表中
首先创建该表启动 Oracle 数据库特别版以系统管理员身份登录如果还没有释放示例 HR 用户请将其释放按照特别版安装附带的入门指南中的指示操作请注意默认情况下HR 用户被赋予 RESOURCE 角色在这里赋予该用户 DBA 角色这样就可以使用该帐户管理 CMS 应用程序的数据库方面了当然不会使用 HR 用户帐户进行在线访问只用它管理数据库
现在可以使用对象浏览器或通过执行 SQL Commands 窗口创建新表下面是创建该表的代码
CREATE TABLE WEB_CONTENT (
page_id NUMBER PRIMARY KEY
page_content VARCHAR()
);
由于该表是使用 HR 用户帐户创建的因此该表归 HR 帐户所有并位于 HR 模式中并且在明确授予其他用户访问该表的权限前其他用户无法访问该表如果不信可以创建一个新用户用该用户访问 WEB_CONTENT 表试试
现在创建两个新用户CMS_USER 和 CMS_EDITOR最终将授予 CMS_USER 对 WEB_CONTENT 表的只读权限并将该用户用作为匿名 Web 用户提供内容的数据库帐户CMS_EDITOR 帐户将在该表上拥有更多权限将被用作 CMS 编辑的帐户(该帐户需要更改和维护该表中的数据)
可以使用 XE 的图形界面或通过执行以下命令创建新用户
CREATE USER cms_user IDENTIFIED BY cms_user;
CREATE USER cms_editor IDENTIFIED BY cms_editor;(出于简化的目的此处的口令与用户名对应)
为了让这两个帐户都登录数据库我们需要赋予它们 CONNECT 角色为此在 XE 图形界面的 Administration/Database Users 部分选中用户信息下的 CONNECT 复选框或执行以下命令
GRANT CONNECT to cms_user;
GRANT CONNECT to cms_editor;
现在如果尝试以 CMS_USER 或 CMS_EDITOR 用户登录并试图从 WEB_CONTENT 表读取数据 (select * from hrweb_content;)将遇到以下错误
ORA:table or view does not exist
为了访问数据或仅是看到表需要授予 CMS_USER 和 CMS_EDITOR 帐户对 WEB_CONTENT 表的只读权限
GRANT SELECT on hrweb_content to cms_user;
GRANT SELECT on hrweb_content to cms_editor;
以上代码使这两个帐户可以对 WEB_CONTENT 表执行 SELECT 语句如果尝试执行其他语句则会遇到错误例如插入一行
INSERT INTO hrweb_content (page_idpage_content) VALUES (hello world);
将产生错误消息
ORA:insufficient privileges
要允许 CMS_EDITOR 更改该表的内容需要授予以下权限
GRANT INSERTUPDATEDELETE on hrweb_content to cms_editor;
从现在起CMS_EDITOR 帐户可以对 WEB_CONTENT 表执行 INSERTUPDATE 和 DELETE 语句
您看这有多简单!可见通过角色管理权限是更有效的方法如果使用的 Oracle 数据库不是 XE可以执行如下操作
创建角色
CREATE ROLE reader;
CREATE ROLE writer;
授予角色权限
GRANT SELECT ON web_content TO reader;
GRANT INSERTUPDATEDELETE ON web_content TO writer;
赋予用户角色
GRANT reader TO cms_user;
GRANT reader TO cms_editor; (they need to read too)
GRANT writer TO cms_editor;
请注意如果更改 READER 角色的定义则这些更改会影响所有具有该角色的用户帐户如果是直接将权限授予用户的则必须逐个更新每个用户帐户
完成上述步骤后可以配置 PHP 应用程序使之对由匿名 Web 用户请求的所有数据库连接均使用 CMS_USER 帐户对由受口令保护的管理页面引发的连接使用 CMS_EDITOR 帐户现在即使公共 Web 表单受到攻击该攻击对数据库的影响将微乎其微这是因为 CMS_USER 帐户仅具有只读权限
结论
在本文中我们只是简单介绍了 Oracle 数据访问安全性的一些最基本的特性此外Oracle 还有许多其他特性可把您的 Web 应用程序的安全性提高到一个新的等级 — 包括虚拟专用数据库 (VPD) 和标签安全性