尝试限制对 Oracle DB 的访问以进行 运行 查询 - 设计建议
Trying to limit access to Oracle DB for running queries - Design suggestion
我正在开发 oracle DB 的 Web 界面,其中:-
- 用户可以请求访问特定模式
- 如果他被授予访问权限,他应该能够 运行 仅查询该架构。
(所有其他查询,如 Other schemas、sys table、all_tables、dual 应被拒绝)
我创建了一个只读用户,可以访问该数据库中的任何 table(NOT SYS)。
现在,我面临的问题是:-
1. 如果该数据库有两个模式 schema1 和 schema2 并且用户可以根据元数据访问 schema1 并且如果他尝试 运行 schema2.table 它将 运行 因为 read_only用户拥有 any_table 权限。
2. 他可以 运行 查询 all_tables(不空闲)
这可以通过以下任一方式解决:-
方法 1:为每个模式创建用户并向该用户授予 schema.table* 权限。
问题 :-
1. 如果有 100 个模式,将有 100 个这样的用户。
2. 如果schema中有一个新的table,需要给新的tables.
赋予明确的权限
方法 2:我正在考虑使用 Regex 方法来解析用户提供的查询,并且只允许 schema1.table 如果他被批准用于 say schema1。如果他尝试 运行 schema2.table 它将失败。
问题:-
可能有很多极端情况,例如子查询、联接等。
有没有更好的办法解决这个问题
您似乎在描述一个普通的客户端-服务器场景。
如果您的最终用户是您所描述的数据库模式,那么您应该实施数据库 "roles"。分配对象对数据库 "roles" 的访问权限,然后根据您的安全定义将这些 "roles" 分配给最终用户。
http://docs.oracle.com/database/121/SQLRF/statements_6014.htm
要避免 "schema1.table" 和 "schema2.table",您可以实施数据库同义词。
https://docs.oracle.com/database/121/SQLRF/statements_7001.htm
同时使用 "roles" + "synonyms" 您将拥有足够的控制权(安全性)并且易于管理。
这里有一些 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
忘记解析吧,准确解析 Oracle SQL 几乎是不可能的。相反,使用 PLAN_TABLE
填充
EXPLAIN PLAN
查找依赖项。
- 为每个语句生成一个唯一的 ID。
- 通过运行
explain plan set statement_id = 'UNIQUE_ID' for $$SELECT_STATEMENT$$
. 生成每条语句的执行计划
- 查询
PLAN_TABLE
以查找查询引用的架构。
根据一些快速测试,这似乎适用于 tables、系统 tables、DUAL、同义词和视图。
至少在这些情况下它不会起作用。
从计划中完全删除 table 的优化器转换。例如,下面的查询引用了 TABLE3,尽管它没有出现在
执行计划,因为它没有被使用。这些都是罕见的情况,可能不是真正的问题。
select *
from table1
where exists (select (select count(*) from table3) from table2);
- 过程代码,如函数和类型,不会出现在执行计划中。保护自定义程序代码可能需要不同的方法。例如,可能需要在游标中用SELECT语句动态创建一个临时过程,然后递归地检查
DBA_DEPENDENCIES
。
例子
创建示例架构。
create table table1(a number);
create table table2(a number primary key);
此查询仅使用本地 table,因此只有 returns 一个用户。
explain plan set statement_id = '1' for
select *
from table1
join table2
on table1.a = table2.a;
select distinct object_owner
from plan_table
where statement_id = '1'
and object_owner is not null;
OBJECT_OWNER
------------
JHELLER
此查询引用系统 tables 和 returns SYS 架构,并且验证失败。
explain plan set statement_id = '2' for
select (select count(*) from all_objects)
from table1
join table2
on table1.a = table2.a;
select distinct object_owner
from plan_table
where statement_id = '2'
and object_owner is not null;
OBJECT_OWNER
------------
JHELLER
SYS
此查询使用 DUAL,应该无法通过验证。检测 DUAL 有点棘手,因为它不是真正的 table.
explain plan set statement_id = '3' for
select (select count(*) from dual)
from table1
join table2
on table1.a = table2.a;
select distinct object_owner
from plan_table
where statement_id = '3'
and object_owner is not null
union all
select distinct 'SYS'
from plan_table
where statement_id = '3'
and operation = 'FAST DUAL';
OBJECT_OWNER
------------
JHELLER
SYS
免责声明
在大多数情况下我不推荐这个解决方案。我同意 Justin 对此请求的担忧。如果遵循标准的 Oracle 安全方法,管理数百个模式和对象可能会更简单。并且最好尽快与不合理的 "security" 请求作斗争。不幸的是,在实践中,这些战斗通常都会失败。
我正在开发 oracle DB 的 Web 界面,其中:-
- 用户可以请求访问特定模式
- 如果他被授予访问权限,他应该能够 运行 仅查询该架构。 (所有其他查询,如 Other schemas、sys table、all_tables、dual 应被拒绝)
我创建了一个只读用户,可以访问该数据库中的任何 table(NOT SYS)。
现在,我面临的问题是:- 1. 如果该数据库有两个模式 schema1 和 schema2 并且用户可以根据元数据访问 schema1 并且如果他尝试 运行 schema2.table 它将 运行 因为 read_only用户拥有 any_table 权限。 2. 他可以 运行 查询 all_tables(不空闲)
这可以通过以下任一方式解决:- 方法 1:为每个模式创建用户并向该用户授予 schema.table* 权限。 问题 :- 1. 如果有 100 个模式,将有 100 个这样的用户。 2. 如果schema中有一个新的table,需要给新的tables.
赋予明确的权限方法 2:我正在考虑使用 Regex 方法来解析用户提供的查询,并且只允许 schema1.table 如果他被批准用于 say schema1。如果他尝试 运行 schema2.table 它将失败。
问题:- 可能有很多极端情况,例如子查询、联接等。
有没有更好的办法解决这个问题
您似乎在描述一个普通的客户端-服务器场景。
如果您的最终用户是您所描述的数据库模式,那么您应该实施数据库 "roles"。分配对象对数据库 "roles" 的访问权限,然后根据您的安全定义将这些 "roles" 分配给最终用户。
http://docs.oracle.com/database/121/SQLRF/statements_6014.htm
要避免 "schema1.table" 和 "schema2.table",您可以实施数据库同义词。
https://docs.oracle.com/database/121/SQLRF/statements_7001.htm
同时使用 "roles" + "synonyms" 您将拥有足够的控制权(安全性)并且易于管理。
这里有一些 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
忘记解析吧,准确解析 Oracle SQL 几乎是不可能的。相反,使用 PLAN_TABLE
填充
EXPLAIN PLAN
查找依赖项。
- 为每个语句生成一个唯一的 ID。
- 通过运行
explain plan set statement_id = 'UNIQUE_ID' for $$SELECT_STATEMENT$$
. 生成每条语句的执行计划
- 查询
PLAN_TABLE
以查找查询引用的架构。
根据一些快速测试,这似乎适用于 tables、系统 tables、DUAL、同义词和视图。
至少在这些情况下它不会起作用。
从计划中完全删除 table 的优化器转换。例如,下面的查询引用了 TABLE3,尽管它没有出现在 执行计划,因为它没有被使用。这些都是罕见的情况,可能不是真正的问题。
select * from table1 where exists (select (select count(*) from table3) from table2);
- 过程代码,如函数和类型,不会出现在执行计划中。保护自定义程序代码可能需要不同的方法。例如,可能需要在游标中用SELECT语句动态创建一个临时过程,然后递归地检查
DBA_DEPENDENCIES
。
例子
创建示例架构。
create table table1(a number);
create table table2(a number primary key);
此查询仅使用本地 table,因此只有 returns 一个用户。
explain plan set statement_id = '1' for
select *
from table1
join table2
on table1.a = table2.a;
select distinct object_owner
from plan_table
where statement_id = '1'
and object_owner is not null;
OBJECT_OWNER
------------
JHELLER
此查询引用系统 tables 和 returns SYS 架构,并且验证失败。
explain plan set statement_id = '2' for
select (select count(*) from all_objects)
from table1
join table2
on table1.a = table2.a;
select distinct object_owner
from plan_table
where statement_id = '2'
and object_owner is not null;
OBJECT_OWNER
------------
JHELLER
SYS
此查询使用 DUAL,应该无法通过验证。检测 DUAL 有点棘手,因为它不是真正的 table.
explain plan set statement_id = '3' for
select (select count(*) from dual)
from table1
join table2
on table1.a = table2.a;
select distinct object_owner
from plan_table
where statement_id = '3'
and object_owner is not null
union all
select distinct 'SYS'
from plan_table
where statement_id = '3'
and operation = 'FAST DUAL';
OBJECT_OWNER
------------
JHELLER
SYS
免责声明
在大多数情况下我不推荐这个解决方案。我同意 Justin 对此请求的担忧。如果遵循标准的 Oracle 安全方法,管理数百个模式和对象可能会更简单。并且最好尽快与不合理的 "security" 请求作斗争。不幸的是,在实践中,这些战斗通常都会失败。