Re: SQL Property Graph Queries (SQL/PGQ)

From: Henson Choi <assam258(at)gmail(dot)com>
To: Ajay Pal <ajay(dot)pal(dot)k(at)gmail(dot)com>
Cc: Ashutosh Bapat <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com>, Peter Eisentraut <peter(at)eisentraut(dot)org>, Amit Langote <amitlangote09(at)gmail(dot)com>, Junwang Zhao <zhjwpku(at)gmail(dot)com>, Vik Fearing <vik(at)postgresfriends(dot)org>, Imran Zaheer <imran(dot)zhir(at)gmail(dot)com>, pgsql-hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: SQL Property Graph Queries (SQL/PGQ)
Date: 2026-01-22 11:56:30
Message-ID: CAAAe_zCfUVeSQSEEW3bAvof1XEs-epS9FTJ78_E3dykYZ9qCdA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hi Ajay,

I looked into this and it appears to be expected PostgreSQL behavior rather
than a GRAPH_TABLE-specific issue.

2026년 1월 22일 (목) PM 7:44, Ajay Pal <ajay(dot)pal(dot)k(at)gmail(dot)com>님이 작성:

> Observation on patch v20260113-0001: GRAPH_TABLE queries are bypassing
> Row-Level Security checks. A low_priv_user is able to access sensitive
> data across the entire table, even though the RLS policy should
> restrict the result set to one non-sensitive row.
>
> reproducible case:-
>
> CREATE TABLE parent_node (id int PRIMARY KEY, secret text);
> CREATE TABLE child_node () INHERITS (parent_node);
>
> INSERT INTO child_node VALUES (1, 'Sensitive');
> INSERT INTO child_node VALUES (2, 'not Sensitive');
>
> CREATE ROLE low_priv_user;
> GRANT SELECT ON parent_node TO low_priv_user;
> GRANT SELECT ON child_node TO low_priv_user;
>
> ALTER TABLE child_node ENABLE ROW LEVEL SECURITY;
> -- Policy: user cannot see rows where secret contains 'Sensitive'
> CREATE POLICY p_hide_sensitive ON child_node TO low_priv_user USING
> (secret !~ 'Sensitive');
>
> CREATE PROPERTY GRAPH security_graph VERTEX TABLES (parent_node);
> GRANT SELECT ON PROPERTY GRAPH security_graph TO low_priv_user;
>
> -- TEST: As low_priv_user, this query should return 0 rows.
> SET ROLE low_priv_user;
> postgres=> SELECT * FROM GRAPH_TABLE (security_graph MATCH (n) COLUMNS
> (n.secret));
> secret
> ---------------
> Sensitive
> not Sensitive
> (2 rows)
>

Running a plain SQL query on the same setup shows identical results:

SELECT secret FROM parent_node;
secret
---------------
Sensitive
not Sensitive
(2 rows)

In PostgreSQL, when querying a parent table, child table's RLS policies are
not applied - only the parent's policies take effect. This is by design.

This behavior is tested in src/test/regress/sql/rowsecurity.sql (lines
374-414).

The fix would be to enable RLS on parent_node instead of child_node.

> Thanks
> Ajay
>
> On Tue, Jan 13, 2026 at 9:44 PM Ashutosh Bapat
> <ashutosh(dot)bapat(dot)oss(at)gmail(dot)com> wrote:
> >
> > On Tue, Jan 13, 2026 at 3:53 PM Peter Eisentraut <peter(at)eisentraut(dot)org>
> wrote:
> > >
> > > I have a small fixup patch for your 20260102 patches, attached.
> > >
> > > - needs additional #include because of recent changes elsewhere
> > > - copyright year updates
> > > - various typos
> > > - some style changes related to palloc APIs
> >
> > All changes look good.
> >
> > Looks like you have reviewed patches 0002-onwards. I removed 0004
> > which was erroneously removing the | handling from ecpg lexer as you
> > pointed out earlier. Squashed all other patches along with your small
> > fixup patch. Attached is the resultant single patch.
> >
> > --
> > Best Wishes,
> > Ashutosh Bapat
>

Thanks,
Henson

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Shlok Kyal 2026-01-22 12:04:25 Re: Skipping schema changes in publication
Previous Message Peter Eisentraut 2026-01-22 11:56:25 Re: commented out code