我正在开发一个oracle DB的web界面,其中: -
-
用户可以要求访问特定模式
-
如果他被授予访问权限,他应该能够仅在该模式上运行查询 . (所有其他查询,如其他模式,sys表,all_tables,dual应该被拒绝)
我创建了一个只读用户,可以访问该DB中的任何表(NOT SYS) .
现在,我面临的问题是: - 1.如果该DB有两个模式schema1和schema2,并且用户可以根据元数据访问schema1,并且如果他尝试运行schema2.table,它将运行,因为read_only用户具有any_table权限 . 他可以在all_tables上运行查询(这不是空闲的)
这可以通过以下任一方法解决: - 方法1:为每个模式创建用户并向该用户授予schema.table *特权 . 问题: - 1.如果有100个模式,将有100个这样的用户 . 2.如果模式中有新表,则需要为新表授予显式权限 .
方法2:我正在考虑使用Regex方法来解析用户提供的查询,并且如果他被批准为schema1,则只允许schema1.table . 如果他试图运行schema2.table它将失败 .
问题: - 可能有许多极端情况,如子查询,连接等 .
有没有更好的方法来解决这个问题 .
2 回答
忘记解析,几乎不可能准确地解析Oracle SQL . 而是使用
EXPLAIN PLAN
填充的PLAN_TABLE
来查找依赖项 .为每个语句生成唯一ID .
通过运行
explain plan set statement_id = 'UNIQUE_ID' for $$SELECT_STATEMENT$$
为每个语句生成执行计划 .查询
PLAN_TABLE
以查找查询引用的模式 .基于一些快速测试,这似乎适用于表,系统表,DUAL,同义词和视图 .
它至少在这些情况下不起作用 .
DBA_DEPENDENCIES
.Examples
创建示例模式 .
此查询仅使用本地表,因此仅返回一个用户 .
此查询引用系统表并返回SYS模式,并且验证失败 .
此查询使用DUAL并且应该验证失败 . 检测DUAL有点棘手,因为它不是真正的表 .
Disclaimer
在大多数情况下,我不建议使用此解决方案 . 我同意贾斯汀对这一要求的担忧 . 如果它遵循标准的Oracle安全方法,那么管理数百个模式和对象可能会更简单 . 并且最好不要迟早地打击不合理的“安全”请求 . 不幸的是,在实践中,这些战斗通常会丢失 .
您似乎正在描述一个普通的客户端 - 服务器方案 .
如果最终用户是您描述的数据库模式,那么您应该实现数据库“角色” . 分配对象访问数据库“角色”,然后根据您的安全定义将这些“角色”分配给最终用户 .
http://docs.oracle.com/database/121/SQLRF/statements_6014.htm
要避免使用“schema1.table”和“schema2.table”,您可以实现数据库同义词 .
https://docs.oracle.com/database/121/SQLRF/statements_7001.htm
使用“角色”“同义词”,您将拥有足够的控制(安全性)和易于管理 .
这里有一些Oracle安全准则:
http://docs.oracle.com/cd/B28359_01/network.111/b28531/guidelines.htm#DBSEG009
http://www.oracle.com/technetwork/articles/entarch/arch-approach-inf-sec-360705.pdf