Re: [HACKERS] Security leak with trigger functions?

2007-01-31 Thread Bruce Momjian

Added to TODO:

 * Tighten trigger permission checks

   http://archives.postgresql.org/pgsql-hackers/2006-12/msg00564.php

and:

 * Tighten function permission checks

  http://archives.postgresql.org/pgsql-hackers/2006-12/msg00568.php


---

Tom Lane wrote:
 Florian G. Pflug [EMAIL PROTECTED] writes:
  Is this true for on-select rules too? In that case, couldn't any
  user run his code as postmaster by creating an appropriate on-select
  rule and waiting until somebody/cron backups the database using pg_dump?
 
 I don't see any issue for views' on-select rules; they wouldn't get
 executed during either dump or reload.
 
 It does seem like there are some other potential hazards once you start
 thinking this way:
 
 * Datatype I/O functions: the output function will be run as superuser
 during pg_dump, and the input function during restore.  I think this is
 not an attack spot today because I/O functions can only be written in
 C, but we'd have to think about the consequences before allowing I/O
 functions in trusted P/L languages.  (Perhaps arrange for I/O functions
 to be run as if setuid to their owner?  Could be expensive...)
 
 * Functions associated with indexes would get run during restore:
 both the datatype-related index support functions, and any functions
 used in functional indexes.  This might be OK because we require
 such functions to be immutable, but I do not think the link from
 immutable to can't write database is currently air-tight.
 
 * Functions in CHECK constraints (either table or domain constraints)
 would be executed during restores.  There is not an immutability
 constraint for these currently, although arguably it'd be reasonable
 to require?
 
 * Trigger functions: not executed during pg_dump, nor during a full
 restore, but they *would* be executed during a data-only restore if
 you'd not used --disable-triggers.
 
 * ON INSERT rules: likewise, executed during data-only restores,
 possibly resulting in execution of user-defined functions.
 
 During restores, we normally set the userid to be the table owner while
 loading data into a particular table, which would mostly close these
 holes except that I think a function can revert the session
 authorization to be whatever the outermost user id is.  Probably we need
 to tighten up the conditions under which a SET SESSION AUTHORIZATION can
 be reverted within a function.
 
   regards, tom lane
 
 ---(end of broadcast)---
 TIP 5: don't forget to increase your free space map settings

-- 
  Bruce Momjian   [EMAIL PROTECTED]
  EnterpriseDBhttp://www.enterprisedb.com

  + If your life is a hard drive, Christ can be your backup. +

---(end of broadcast)---
TIP 6: explain analyze is your friend


Re: [HACKERS] Security leak with trigger functions?

2006-12-17 Thread Florian G. Pflug

Tom Lane wrote:

Martijn van Oosterhout kleptog@svana.org writes:

The trigger never runs as the owner of the table AIUI, only ever as the
definer of the function or as session user.


Yeah.  This might itself be seen as a bug: I think you could make a
reasonable case that the default behavior ought to be to run as the
table owner (but still overridable if trigger function is SECURITY
DEFINER, of course).  In the current situation a table owner can use
a trigger function as a trojan horse against anyone modifying the
table.


Is this true for on-select rules too? In that case, couldn't any
user run his code as postmaster by creating an appropriate on-select
rule and waiting until somebody/cron backups the database using pg_dump?

Or is pg_dump smart enough to skip dumping tables with on-select rules?

greetings, Florian Pflug


---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
  subscribe-nomail command to [EMAIL PROTECTED] so that your
  message can get through to the mailing list cleanly


Re: [HACKERS] Security leak with trigger functions?

2006-12-17 Thread Tom Lane
Florian G. Pflug [EMAIL PROTECTED] writes:
 Is this true for on-select rules too? In that case, couldn't any
 user run his code as postmaster by creating an appropriate on-select
 rule and waiting until somebody/cron backups the database using pg_dump?

I don't see any issue for views' on-select rules; they wouldn't get
executed during either dump or reload.

It does seem like there are some other potential hazards once you start
thinking this way:

* Datatype I/O functions: the output function will be run as superuser
during pg_dump, and the input function during restore.  I think this is
not an attack spot today because I/O functions can only be written in
C, but we'd have to think about the consequences before allowing I/O
functions in trusted P/L languages.  (Perhaps arrange for I/O functions
to be run as if setuid to their owner?  Could be expensive...)

* Functions associated with indexes would get run during restore:
both the datatype-related index support functions, and any functions
used in functional indexes.  This might be OK because we require
such functions to be immutable, but I do not think the link from
immutable to can't write database is currently air-tight.

* Functions in CHECK constraints (either table or domain constraints)
would be executed during restores.  There is not an immutability
constraint for these currently, although arguably it'd be reasonable
to require?

* Trigger functions: not executed during pg_dump, nor during a full
restore, but they *would* be executed during a data-only restore if
you'd not used --disable-triggers.

* ON INSERT rules: likewise, executed during data-only restores,
possibly resulting in execution of user-defined functions.

During restores, we normally set the userid to be the table owner while
loading data into a particular table, which would mostly close these
holes except that I think a function can revert the session
authorization to be whatever the outermost user id is.  Probably we need
to tighten up the conditions under which a SET SESSION AUTHORIZATION can
be reverted within a function.

regards, tom lane

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [HACKERS] Security leak with trigger functions?

2006-12-15 Thread Albe Laurenz
Peter Eisentraut wrote:
 Tom Lane wrote:
 Peter Eisentraut [EMAIL PROTECTED] writes:
 Tom Lane wrote:
 The question in my mind is what privilege to check and when.

 By extrapolation of the SQL standard, I'd say we'd need to check
 the EXECUTE privilege of the function at run time.

 Certainly EXECUTE privilege is what to check, but whose privilege?
 
 PostgreSQL only allows a trigger action of call this function, so in

 the SQL standard context that would mean we'd need to check the
EXECUTE 
 privilege of the owner of the trigger.  The trick is figuring out who 
 the owner is.  If it's the owner of the table, then TRIGGER privilege 
 is effectively total control over the owner of the table.  If it's 
 whoever created the trigger, it might be useful, but I don't see how 
 that is compatible with the intent of the SQL standard.

Looking at pg_trigger I have the impression that there is no such thing
as an 'owner of a trigger', and consequently the owner of the trigger
would automatically be the table owner.

I understand the reservations about the TRIGGER privilege, but I think
that it is obvious anyway that anybody who can add a trigger can
basically do everything with the table.

When adding a trigger, I would check if both the table owner and
the user who adds the trigger have EXECUTE privilege on the function.
That doesn't seem too restrictive to me.

For trigger execution, I see two options:
1) Check for EXECUTE privilege of the table owner at statement begin
   time, as Tom Lane suggested. We cannot be sure if the trigger would
   actually be executed, right? Should there be an error message even
   when the trigger is not fired? Or should the trigger be silently
   disabled?
2) Whenever EXECUTE on a function is revoked, disable triggers on all
   tables whose owners have now no longer execute privilege.
   This should probably not be silent and require something like a
   CASCADE option for REVOKE...
   Also, there'd have to be an update whenever table ownership is
   changed...
   Seems quite difficult, but would save checking at runtime.

Yours,
Laurenz Albe

---(end of broadcast)---
TIP 1: if posting/reading through Usenet, please send an appropriate
   subscribe-nomail command to [EMAIL PROTECTED] so that your
   message can get through to the mailing list cleanly


Re: [HACKERS] Security leak with trigger functions?

2006-12-15 Thread Andrew Dunstan

Albe Laurenz wrote:

Looking at pg_trigger I have the impression that there is no such thing
as an 'owner of a trigger', and consequently the owner of the trigger
would automatically be the table owner.

I understand the reservations about the TRIGGER privilege, but I think
that it is obvious anyway that anybody who can add a trigger can
basically do everything with the table.

  


Isn't the problem that they can do more than just things with the table? 
If the trigger runs as the owner of the table it can do *anything* the 
owner can do. So if we allow the alter privilege to include ability to 
place a trigger then that privilege includes everything the owner can do 
(including granting/revoking other privileges). Surely that is not what 
was intended. Arguably we should invent a concept of an explicit trigger 
owner.


cheers

andrew

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [HACKERS] Security leak with trigger functions?

2006-12-15 Thread Martijn van Oosterhout
On Fri, Dec 15, 2006 at 11:52:33AM -0500, Andrew Dunstan wrote:
 Isn't the problem that they can do more than just things with the table? 
 If the trigger runs as the owner of the table it can do *anything* the 
 owner can do. So if we allow the alter privilege to include ability to 
 place a trigger then that privilege includes everything the owner can do 
 (including granting/revoking other privileges). Surely that is not what 
 was intended. Arguably we should invent a concept of an explicit trigger 
 owner.

I thought the problem was the other way round. That some person created
a function as SECURITY DEFINER but restricted EXECUTE permissions. And
now anybody can create a table and use that function as a trigger and
it will be executed even though neither the owner of the table nor the
person executing the trigger has EXECUTE permissions.

Triggers don't have owners because like you said, the table owner
controls them. The point is that there's no check that the table owner
is actually allowed to execute the function being used as trigger.

The trigger never runs as the owner of the table AIUI, only ever as the
definer of the function or as session user.

Have a nice day,
-- 
Martijn van Oosterhout   kleptog@svana.org   http://svana.org/kleptog/
 From each according to his ability. To each according to his ability to 
 litigate.


signature.asc
Description: Digital signature


Re: [HACKERS] Security leak with trigger functions?

2006-12-15 Thread Andrew Dunstan

Martijn van Oosterhout wrote:

On Fri, Dec 15, 2006 at 11:52:33AM -0500, Andrew Dunstan wrote:
  
Isn't the problem that they can do more than just things with the table? 
If the trigger runs as the owner of the table it can do *anything* the 
owner can do. So if we allow the alter privilege to include ability to 
place a trigger then that privilege includes everything the owner can do 
(including granting/revoking other privileges). Surely that is not what 
was intended. Arguably we should invent a concept of an explicit trigger 
owner.



I thought the problem was the other way round. That some person created
a function as SECURITY DEFINER but restricted EXECUTE permissions. And
now anybody can create a table and use that function as a trigger and
it will be executed even though neither the owner of the table nor the
person executing the trigger has EXECUTE permissions.

Triggers don't have owners because like you said, the table owner
controls them. The point is that there's no check that the table owner
is actually allowed to execute the function being used as trigger.

The trigger never runs as the owner of the table AIUI, only ever as the
definer of the function or as session user.


  


OK, sorry for the confusion.

cheers

andrew


---(end of broadcast)---
TIP 7: You can help support the PostgreSQL project by donating at

   http://www.postgresql.org/about/donate


Re: [HACKERS] Security leak with trigger functions?

2006-12-15 Thread Tom Lane
Martijn van Oosterhout kleptog@svana.org writes:
 The trigger never runs as the owner of the table AIUI, only ever as the
 definer of the function or as session user.

Yeah.  This might itself be seen as a bug: I think you could make a
reasonable case that the default behavior ought to be to run as the
table owner (but still overridable if trigger function is SECURITY
DEFINER, of course).  In the current situation a table owner can use
a trigger function as a trojan horse against anyone modifying the
table.

And then there's the question of functions run as a result of rule
definitions.  That's a lot harder to fix, but (I think) triggers would
be relatively easy to do something about.

regards, tom lane

---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq


[HACKERS] Security leak with trigger functions?

2006-12-14 Thread Albe Laurenz
Permissions on a trigger function seem not to be checked,
and I can execute a function for which I have no privileges.

I consider this a security leak - or am I missing something?

Here is a complete example:

As superuser, create a trigger function that selects from pg_authid
with SECURITY INVOKER, and REVOKE EXECUTE from public:

test=# \c test postgres
You are now connected to database test as user postgres.
test=# CREATE OR REPLACE FUNCTION insert_oid() RETURNS trigger AS
test-# $$BEGIN SELECT oid INTO NEW.useroid FROM pg_catalog.pg_authid
WHERE rolname = user; RETURN NEW; END;$$
test-# LANGUAGE plpgsql STABLE STRICT SECURITY DEFINER;
CREATE FUNCTION
test=# REVOKE EXECUTE ON FUNCTION insert_oid() FROM public;
REVOKE
test=# SELECT proacl FROM pg_catalog.pg_proc WHERE proname =
'insert_oid';
proacl  
---
 {postgres=X/postgres}
(1 row)

As normal user, try to execute the function or select from
pg_catalog.pg_authid directly; both fail as expected:

test=# \c test laurenz
You are now connected to database test as user laurenz.
test= SELECT insert_oid();
ERROR:  permission denied for function insert_oid
test= SELECT oid FROM pg_catalog.pg_authid WHERE rolname = user;
ERROR:  permission denied for relation pg_authid

Create a temporary table, define a trigger BEFORE INSERT using the
function that we cannot execute:

test= CREATE TEMP TABLE lautest (id integer PRIMARY KEY, useroid oid
NOT NULL);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index
lautest_pkey for table lautest
CREATE TABLE
test= CREATE TRIGGER insert_oid BEFORE INSERT ON lautest FOR EACH ROW
EXECUTE PROCEDURE insert_oid();
CREATE TRIGGER

Insert a row into the table.
The trigger function is executed, and I have selected a value from
pg_authid!

test= INSERT INTO lautest (id) VALUES (1);
INSERT 0 1
test= SELECT * FROM lautest;
 id | useroid 
+-
  1 |  10
(1 row)

Yours,
Laurenz Albe

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [HACKERS] Security leak with trigger functions?

2006-12-14 Thread Tom Lane
Albe Laurenz [EMAIL PROTECTED] writes:
 Permissions on a trigger function seem not to be checked,
 and I can execute a function for which I have no privileges.

Only if it's a trigger function, but I agree this is not very good.
The question in my mind is what privilege to check and when.

I believe the check probably ought to be whether the table owner can
call the function (certainly not the person doing the command that
invokes the trigger).  However, that raises the question of whether
having a separate TRIGGER privilege to attach triggers to tables isn't
itself a security hole: it means someone who might not himself have call
privileges could cause other people to call a function.  We just removed
the separate RULE privilege, and said you must be table owner to put a
rule on a table, for exactly analogous reasons.

The other question is when to check it.  If we check only at CREATE
TRIGGER time then there's the problem that revoking execute privilege
on a trigger function would not do what you'd expect.  OTOH checking
at every trigger call seems quite unpleasant.  Would it be all right
to check all the triggers once at statement start (eg, in
ExecBSInsertTriggers) whether or not they actually get called?

BTW, I just noticed another bug in the trigger stuff: in a statement
with multiple target relations, such as UPDATE across an inheritance
tree, ExecBSUpdateTriggers and friends get called only on the first
(parent) target relation.  Hence any statement-level triggers on child
tables aren't invoked.  This probably isn't very critical today, but
it would be if we use those functions to enforce permissions checks.

regards, tom lane

---(end of broadcast)---
TIP 7: You can help support the PostgreSQL project by donating at

http://www.postgresql.org/about/donate


Re: [HACKERS] Security leak with trigger functions?

2006-12-14 Thread Peter Eisentraut
Tom Lane wrote:
 The question in my mind is what privilege to check and when.

By extrapolation of the SQL standard, I'd say we'd need to check the 
EXECUTE privilege of the function at run time.

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/

---(end of broadcast)---
TIP 2: Don't 'kill -9' the postmaster


Re: [HACKERS] Security leak with trigger functions?

2006-12-14 Thread Tom Lane
Peter Eisentraut [EMAIL PROTECTED] writes:
 Tom Lane wrote:
 The question in my mind is what privilege to check and when.

 By extrapolation of the SQL standard, I'd say we'd need to check the 
 EXECUTE privilege of the function at run time.

Certainly EXECUTE privilege is what to check, but whose privilege?

regards, tom lane

---(end of broadcast)---
TIP 3: Have you checked our extensive FAQ?

   http://www.postgresql.org/docs/faq


Re: [HACKERS] Security leak with trigger functions?

2006-12-14 Thread Peter Eisentraut
Tom Lane wrote:
 Peter Eisentraut [EMAIL PROTECTED] writes:
  Tom Lane wrote:
  The question in my mind is what privilege to check and when.
 
  By extrapolation of the SQL standard, I'd say we'd need to check
  the EXECUTE privilege of the function at run time.

 Certainly EXECUTE privilege is what to check, but whose privilege?

SQL allows a trigger action to be a more or less random list of 
statements, which are checked at trigger run time against the 
privileges of the owner of the trigger.

(The authorization identifier of the owner of the schema that includes 
the trigger descriptor of TR is pushed onto the authorization stack.)

PostgreSQL only allows a trigger action of call this function, so in 
the SQL standard context that would mean we'd need to check the EXECUTE 
privilege of the owner of the trigger.  The trick is figuring out who 
the owner is.  If it's the owner of the table, then TRIGGER privilege 
is effectively total control over the owner of the table.  If it's 
whoever created the trigger, it might be useful, but I don't see how 
that is compatible with the intent of the SQL standard.

-- 
Peter Eisentraut
http://developer.postgresql.org/~petere/

---(end of broadcast)---
TIP 5: don't forget to increase your free space map settings


Re: [HACKERS] Security leak with trigger functions?

2006-12-14 Thread Josh Berkus
Peter,

 PostgreSQL only allows a trigger action of call this function, so in
 the SQL standard context that would mean we'd need to check the EXECUTE
 privilege of the owner of the trigger.  The trick is figuring out who
 the owner is.  If it's the owner of the table, then TRIGGER privilege
 is effectively total control over the owner of the table.  If it's
 whoever created the trigger, it might be useful, but I don't see how
 that is compatible with the intent of the SQL standard.

If that's the case, then a separate TRIGGER priveledge would seem to be 
superfluous.

One thing to think about, though; our model allows granting ALTER 
privelidge on a table to roles other than the table owner.  It would seem 
kind of inconsistent to be able to grant non-owner roles the ability to 
drop a column, but restrict only the owner to adding a trigger.  For one 
thing, if you have a non-owner role which has ALTER permission and wants 
to add an FK, how would that work?

-- 
--Josh

Josh Berkus
PostgreSQL @ Sun
San Francisco


---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org


Re: [HACKERS] Security leak with trigger functions?

2006-12-14 Thread Tom Lane
Josh Berkus josh@agliodbs.com writes:
 ... we'd need to check the EXECUTE
 privilege of the owner of the trigger.  The trick is figuring out who
 the owner is.  If it's the owner of the table, then TRIGGER privilege
 is effectively total control over the owner of the table.

 If that's the case, then a separate TRIGGER priveledge would seem to be 
 superfluous.

Yeah, you could make a good case for removing TRIGGER privilege and
making it be an ownership check, as we just did for RULE privilege.

 One thing to think about, though; our model allows granting ALTER 
 privelidge on a table to roles other than the table owner.

Huh?  ALTER requires ownership.

regards, tom lane

---(end of broadcast)---
TIP 4: Have you searched our list archives?

   http://archives.postgresql.org