-
Notifications
You must be signed in to change notification settings - Fork 38
Description
Summary
pgschema plan produces a false-positive ALTER POLICY that silently truncates string literals containing dots in USING/WITH CHECK expressions. Applying this plan would break RLS policies.
Environment
- pgschema: built from main (post-1.7.4, commit including fix: correct LANGUAGE for overloaded functions with mixed languages (#368) #370 fix)
- PostgreSQL: 18.2
Minimal repro
CREATE SCHEMA s;
CREATE SCHEMA auth;
CREATE FUNCTION auth.has_scope(p_scope text) RETURNS boolean
LANGUAGE sql STABLE AS $$ SELECT p_scope IS NOT NULL $$;
CREATE ROLE test_role;
CREATE TABLE s.items(id int);
ALTER TABLE s.items ENABLE ROW LEVEL SECURITY;
CREATE POLICY manage_items ON s.items
FOR UPDATE TO test_role
USING (auth.has_scope('s.manage'))
WITH CHECK (auth.has_scope('s.manage'));# 1. Dump
pgschema dump --schema s --db <db> --user <user> > /tmp/s_dump.sql
# 2. Verify dump is correct — should contain 's.manage'
grep has_scope /tmp/s_dump.sql
# Expected: auth.has_scope('s.manage')
# 3. Plan (expect empty — no changes)
pgschema plan --schema s --db <db> --user <user> \
--file /tmp/s_dump.sql \
--plan-host localhost --plan-db <db> --plan-user <user> \
--output-sql /dev/stdoutExpected
Empty plan (dump matches current state).
Actual
ALTER POLICY manage_items ON items USING (auth.has_scope('manage')) WITH CHECK (auth.has_scope('manage'));The string literal 's.manage' is truncated to 'manage' — the s. prefix (which matches the schema name) is stripped.
Impact
- Destructive: applying this plan silently breaks RLS policies by corrupting function arguments
- Silent data corruption: no error or warning, the plan looks valid
- Affects any policy where a string literal happens to contain
<schema_name>.as a prefix
Reactions are currently unavailable