撤消对表pg_proc上的postgresql中不起作用的特定列的访问

3pi*_*ece 6 sql database postgresql grant

我的目标是只允许特定用户执行特定模式中的函数,按名称列出可用的函数,但不能查看函数的源代码或列出其他模式.

通过执行以下操作,可以实现上述功能而无法列出可用的功能名称:

首先创建一个测试用户角色:

CREATE ROLE test_user WITH LOGIN PASSWORD 'secret';
Run Code Online (Sandbox Code Playgroud)

现在撤消所有模式上公共的所有权限:

REVOKE ALL PRIVILEGES ON DATABASE test_db FROM PUBLIC;
REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA public FROM PUBLIC;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA public FROM PUBLIC;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA public FROM PUBLIC;
REVOKE ALL ON SCHEMA public FROM PUBLIC;

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA function_schema FROM PUBLIC;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA function_schema FROM PUBLIC;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA function_schema FROM PUBLIC;
REVOKE ALL ON SCHEMA function_schema FROM PUBLIC;

REVOKE ALL PRIVILEGES ON ALL TABLES IN SCHEMA table_schema FROM PUBLIC;
REVOKE ALL PRIVILEGES ON ALL FUNCTIONS IN SCHEMA table_schema FROM PUBLIC;
REVOKE ALL PRIVILEGES ON ALL SEQUENCES IN SCHEMA table_schema FROM PUBLIC;
REVOKE ALL ON SCHEMA table_schema FROM PUBLIC;
Run Code Online (Sandbox Code Playgroud)

为测试用户设置受限访问:

GRANT CONNECT ON DATABASE test_db TO test_user;
GRANT USAGE ON SCHEMA function_schema TO test_user;
REVOKE ALL ON SCHEMA public FROM test_user;
REVOKE ALL ON SCHEMA table_schema FROM test_user;
GRANT EXECUTE ON FUNCTION function_schema.function1() TO test_user;
GRANT EXECUTE ON FUNCTION function_schema.function2(integer) TO test_user;
Run Code Online (Sandbox Code Playgroud)

现在隐藏架构结构和代码形成测试用户和公共:

REVOKE SELECT ON TABLE pg_proc FROM public;
REVOKE SELECT ON TABLE pg_proc FROM test_user;
Run Code Online (Sandbox Code Playgroud)

这一切都运行良好,测试用户可以执行这些功能,但是他们看不到函数内部的代码,也看不到模式和表结构.

-

我想允许测试用户现在在test_functions模式中按名称查看函数.我根据GRANT Postgresql 9.3尝试了以下内容(这是在pg_proc中的每一列上授予select):

GRANT SELECT (proname,pronamespace,proowner,prolang,procost,prorows,
provariadic,protransform,proisagg,proiswindow,prosecdef,proleakproof,
proisstrict,proretset,provolatile,pronargs,pronargdefaults,prorettype,
proargtypes,proallargtypes,proargmodes,proargnames,proargdefaults,prosrc,
probin,proconfig,proacl) ON TABLE pg_proc TO test_user;
Run Code Online (Sandbox Code Playgroud)

这样的结果是测试用户没有获得所有相同的选择权限,就好像他们可以访问整个表一样.他们仍然看不到功能名称.

另一个测试是反过来,将select选择到表,然后撤销所有列的REVOKE postgresql 9.3上的select :

GRANT SELECT ON TABLE pg_proc TO test_user;

REVOKE SELECT (proname,pronamespace,proowner,prolang,procost,prorows,
provariadic,protransform,proisagg,proiswindow,prosecdef,proleakproof,
proisstrict,proretset,provolatile,pronargs,pronargdefaults,prorettype,
proargtypes,proallargtypes,proargmodes,proargnames,proargdefaults,prosrc,
probin,proconfig,proacl) ON TABLE pg_proc FROM test_user;
Run Code Online (Sandbox Code Playgroud)

再次这不起作用,他们现在可以看到所有模式,代码和表(在允许的模式上).

似乎特定列的授予/撤销不像文档建议的那样工作.

广泛搜索产生了如何限制对函数中代码的访问,该函数建议只撤销对pg_proc.prosrc列的访问,这显然不适用于上述测试.

我正在使用postgresql 9.3

请随时提出任何其他想到的解决方案.

Pat*_*ick 3

使用列权限应该可行,但可能不是最好的方法。在 PostgreSQL 中以这种方式维护权限是相当繁重的。使用这种方法,您必须为所有受影响的系统目录关系上的各个用户设置和跟踪安全策略。想象一下,当您拥有多个用户时,必须更新您的安全策略。

我建议您不要在关系上应用详细的安全角色,而是锁定系统目录中的所有内容(就像您所做的那样),然后创建视图以有选择地公开部分系统目录(标准设置中已经是这种情况,但显然对于你的情况来说不够严格)。将这些视图上的 SELECT 授予组角色,然后将该组角色授予登录角色(应具有 INHERIT 属性)。这样,您可以更轻松地跟踪您所做的事情并更新您的安全策略,因为所有策略都包含在一组视图(内容)和组角色(可访问性)中。如果您使用的是 PostgreSQL-9.2+,请检查with security-barrier视图上的选项,因为这将防止恶意用户欺骗优化器。