Re: [v9.4] row level security

From: Alexander Korotkov <aekorotkov(at)gmail(dot)com>
To: Kohei KaiGai <kaigai(at)kaigai(dot)gr(dot)jp>
Cc: Oleg Bartunov <obartunov(at)gmail(dot)com>, Greg Smith <greg(at)2ndquadrant(dot)com>, PgHacker <pgsql-hackers(at)postgresql(dot)org>
Subject: Re: [v9.4] row level security
Date: 2013-08-29 12:09:35
Message-ID: CAPpHfdsgMrBnzu9um48O6kwY=_pRFuRrBrHqnA03fCAo8x3-Gg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

On Wed, Aug 28, 2013 at 4:17 PM, Kohei KaiGai <kaigai(at)kaigai(dot)gr(dot)jp> wrote:

> 2013/8/28 Oleg Bartunov <obartunov(at)gmail(dot)com>:
> > btw, there is serious problem with row-level security and constraints.
> For
> > example, user with low security level could use unique constraint to know
> > about existence of a row with higher security. I don't know, what is the
> > best practice to avoid this.
> >
> It is out of scope for this feature. We usually calls this type of
> information
> leakage "covert channel"; that is not avoidable in principle.
> However, its significance is minor, because attacker must know identical
> data to be here, or must have proving for each possible values.
> Its solution is simple. DBA should not use value to be confidential as
> unique
> key. If needed, our recommendation is alternative key, instead of natural
> key,
> because its value itself does not have worth.
>
> I should add a note of caution onto the documentation according to
> the previous consensus, however, I noticed it had gone from the sgml files
> while I was unaware. So, let me add description on the documentation.

I think there is another "covert channel" much more serious than
constrains. You can gather information about hidden data by reading query
plans.

CREATE TABLE test (id SERIAL PRIMARY KEY, value INTEGER);
INSERT INTO test (value) VALUES (1234), (4321), (2356), (6542);
ALTER TABLE test SET ROW SECURITY FOR ALL TO (id % 2 = 1);
CREATE INDEX test_idx ON test (value);

User sees only 1 and 3 rows:

postgres=> select * from test;
id | value
----+-------
1 | 1234
3 | 2356
(2 rows)

But user can probe values column using explain command.

postgres=> set enable_seqscan = off;
SET
postgres=> explain analyze select * from test where value between 1111 and
3333;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Index Scan using test_idx on test (cost=0.13..8.16 rows=1 width=8)
(actual time=0.021..0.024 rows=2 loops=1)
Index Cond: ((value >= 1111) AND (value <= 3333))
Filter: ((id % 2) = 1)
Total runtime: 0.056 ms
(4 rows)

postgres=> explain analyze select * from test where value between 1111 and
5555;
QUERY PLAN
---------------------------------------------------------------------------------------------------------------
Index Scan using test_idx on test (cost=0.13..8.16 rows=1 width=8)
(actual time=0.020..0.024 rows=2 loops=1)
Index Cond: ((value >= 1111) AND (value <= 5555))
Filter: ((id % 2) = 1)
Rows Removed by Filter: 1
Total runtime: 0.057 ms
(5 rows)

In given example user can realize that there is a hidden value in index
between 3334 and 5555. Using dichotomy he can find exact value.
I didn't find if there was discussion about it. This example is only my
first idea about using plans for probing hidden values. Probably, there are
some other ways to do it.
I don't think we can say that indexed data is not sensitive for leakage.
Prohibiting push down of all operators which could be used for such kind of
attacks also doesn't seem acceptable for me because of huge impact to
performance. Another option I see is to hide some sensitive parts of plan
from unprivileged user. There is still a room for timing attack, but it
doesn't seem to be feasible in practice to apply.

------
With best regards,
Alexander Korotkov.

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message MauMau 2013-08-29 12:17:05 Re: [9.3 doc fix] clarification of Solaris versions
Previous Message Heikki Linnakangas 2013-08-29 11:19:33 Re: Spinlock implementation on x86_64 (was Re: Better LWLocks with compare-and-swap (9.4))