Skip site navigation (1) Skip section navigation (2)

Re: [PATCHES] [PATCH] Re: Why READ ONLY transactions?

From: Sean Chittenden <sean(at)chittenden(dot)org>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Christopher Browne <cbbrowne(at)libertyrms(dot)info>,pgsql-patches(at)postgresql(dot)org,Robert Treat <xzilla(at)users(dot)sourceforge(dot)net>,Gavin Sherry <swm(at)linuxworld(dot)com(dot)au>, pgsql-advocacy(at)postgresql(dot)org
Subject: Re: [PATCHES] [PATCH] Re: Why READ ONLY transactions?
Date: 2003-07-30 21:10:26
Message-ID: 20030730211026.GB34647@perrin.int.nxad.com (view raw or flat)
Thread:
Lists: pgsql-advocacypgsql-hackerspgsql-patches
> >> I would NOT call it a "security" provision, as it is fairly
> >> easily defeated using SET TRANSACTION.
> 
> > Um, why not make it an actual full blown security feature by
> > applying the following patch?
> 
> It's not intended to be a security measure, and I would strongly
> resist any attempt to make it so along the lines you propose.

Intended or not, it does work.

> I do not want to try to base real security on GUC settings.  The GUC
> mechanism is not designed to be unsubvertible, it's designed to
> allow convenient administration of a bunch of settings.

I agree that permissions of objects or anything specific should remain
outside of the GUC system, however for global GUC like things, such as
the default mode of a transaction (READ ONLY/READ WRITE), this is
perfect (I think of PostgreSQL's GUC system the same way I do
FreeBSD's sysctl MIB system or Linux's /proc file system: useful for
global things, in appropriate for anything fine grained).  I was
thinking about that this morning, a better name would be
"jail_read_only_transactions" as the GUC contains a user to a read
only transaction.  It could be confusing in that it doesn't force a
transaction to be read only.

> In any case, we already have mechanisms for preventing specific
> users from altering data: that's what GRANT/REVOKE are for.  I don't
> think anyone would have bothered with START TRANSACTION READ ONLY if
> it weren't required by the SQL spec.

Ah, but this falls on its face when you want a user who does have
write access to tables to go through a fixed procedure before opening
up the DB for write access (logging of SELECTs will always require
some goo).  To prevent a user who does have write access
(INSERT/UPDATE/DELETE) to tables from modifying tables before they've
started a transaction inside of the database system (different than
BEGIN, custom function start_txn() that sets up the database for
logging), in every function, I used to have to test to see if the
txn_id was in the temp table.  With the posted patch, I can ensure a
fully auditable and exceedingly secure database (except for malicious
DBAs) that prevents any kind of unlogged abuse. Here's what I'm
planning on doing in my tree:

-- Username joe is any non-dba
ALTER USER joe SET transaction_force_read_only TO TRUE;
ALTER USER joe SET default_transaction_read_only TO TRUE;
CREATE FUNCTION public.start_txn()
       RETURNS BIGINT
       EXTERNAL SECURITY DEFINER
       AS '
       -- Pulls a txn_id from a sequence and stuff value into a temp
       -- table that a user doesn't have write access to.  Once
       -- transaction ID is stored, change the transaction from READ
       -- ONLY to READ WRITE.  Return the txn_id to the user.
' LANGUAGE 'plpgsql';

Before, I had to have every function that modified data test to see if
a txn_id existed in the session temp table.  Now, by relying on the
transaction's mode, I only have to test for that on the tables that I
log when there is SELECT activity, which will cut the number of lines
of pl/PgSQL code by about 1200-1500 lines[1]!

At the very least, it's an easier way of guaranteeing a READ ONLY
database.  Securing a database with GRANT/REVOKE can be tedious and
error prone.  In the case of a PHP Web shop/hacker that hasn't a clue
about quoting data before sending queries to the backend, this is a
nice safety blanket that takes a few seconds to setup (create user
www, alter user, alter user && *poof*, www user is secure).  Right
now, to secure a user, you have to REVOKE INSERT, UPDATE, DELETE on
all tables, schemas and functions running as SECURITY DEFINER that
modify data, whereas jail_read_only_transactions is a simple and
effective blanket.  IMHO, this is a huge 2nd safety belt that's easy
to apply, even though you're right, people _should_ rely on
GRANT/REVOKE.... though GRANT/REVOKE doesn't work in some situations
as mentioned above.

-sc


[1] Pl/PgSQL code + surrounding white space (* >300):

     PERFORM TRUE FROM [temp_tbl]...;
     IF NOT FOUND THEN
	RAISE EXCEPTION ''my error message'';
     END IF;

-- 
Sean Chittenden

In response to

Responses

pgsql-hackers by date

Next:From: Sean ChittendenDate: 2003-07-30 21:33:35
Subject: Re: [PATCH] Re: [pgsql-advocacy] Why READ ONLY transactions?
Previous:From: Christopher BrowneDate: 2003-07-30 21:07:31
Subject: Re: Upgrading my BSDI box, again

pgsql-patches by date

Next:From: Sean ChittendenDate: 2003-07-30 21:33:35
Subject: Re: [PATCH] Re: [pgsql-advocacy] Why READ ONLY transactions?
Previous:From: NicDate: 2003-07-30 19:44:24
Subject: Re: JDBC stored procs doc patch

pgsql-advocacy by date

Next:From: Sean ChittendenDate: 2003-07-30 21:33:35
Subject: Re: [PATCH] Re: [pgsql-advocacy] Why READ ONLY transactions?
Previous:From: Rod TaylorDate: 2003-07-30 20:43:56
Subject: Re: On Domains

Privacy Policy | About PostgreSQL
Copyright © 1996-2014 The PostgreSQL Global Development Group