在 PostgreSQL 中撤销对特定列的访问权限无法在 pg_proc 表上生效。

7
我的目标是仅允许特定用户在特定模式中执行函数,按名称列出可用的函数但不显示函数源代码或列出其他模式。
可以通过以下方法实现上述目标而无需列出可用函数名称的能力:
首先创建一个测试用户角色:
CREATE ROLE test_user WITH LOGIN PASSWORD 'secret';

现在从所有模式中撤销公共权限:
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;

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

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;

现在需要将模式结构和代码从测试用户和公众视野中隐藏:
REVOKE SELECT ON TABLE pg_proc FROM public;
REVOKE SELECT ON TABLE pg_proc FROM test_user;

这一切都运作良好,测试用户可以执行函数,但他们无法看到函数内部的代码,也无法看到模式和表结构。

--

我希望允许测试用户现在按名称查看test_functions模式中的函数。根据GRANT Postgresql 9.3(这是在pg_proc的每个列上授予选择权限)尝试了以下操作:
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;

这里的结果是测试用户没有完全获得与访问整个表相同的选择权限。他们仍然无法看到函数名称。
另一个测试是相反的,授予对表的选择权限,然后根据REVOKE postgresql 9.3撤销所有列的选择权限。
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;

再次尝试失败,他们现在可以看到所有模式、代码和表(允许的模式)。

似乎特定列的授权/撤销不按照文档所述的方式工作。

广泛搜索得出如何限制函数中代码的访问权限,建议仅撤销对pg_proc.prosrc列的访问权限,但从上面的测试中明显无效。

我正在使用postgresql 9.3。

请随时提出任何其他解决方案。

1个回答

3
与列权限一起使用应该可以工作,但在PostgreSQL中,这可能不是最好的方法。以这种方式维护特权相当繁琐。使用此方法,您必须在所有受影响的系统目录关系上为单个用户设置和跟踪安全策略。想象一下,当您有多个用户时,必须更新安全策略。
与其在关系上应用详细的安全角色,我建议您将系统目录中的所有内容锁定(就像您所做的那样),然后创建视图以选择性地公开系统目录的部分内容(标准设置已经如此,但显然对您的情况不够严格)。将GRANT SELECT授予一个组角色,并将该组角色授予登录角色(应具有INHERIT属性)。这样,跟踪您所做的事情并更新安全策略要容易得多,因为所有策略都包含在一组视图(内容)和组角色(可访问性)中。如果您正在使用PostgreSQL-9.2+,请查看视图上的with security-barrier选项,因为这将防止恶意用户通过优化器欺骗。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接