FPW compression leaks information
Now that we have compression of full-page images in WAL, it can be used
to leak sensitive information you're not supposed to see. Somewhat
similar to the recent BREACH and CRIME attacks on SSL, if you can insert
into a table, the compression ratio gives you a hint of how similar the
existing data on the page is to the data you inserted.
That might seem abstract, so let's consider a concrete example. Imagine
that Eve wants to know the password of another user. She can't read
pg_authid directly, but she can change her own password, which causes an
update in pg_authid. The procedure is to:
1. Perform a checkpoint.
2. Call pg_current_xlog_insert_location() to get current WAL position.
3. Change password.
4. Call pg_current_xlog_insert_location() again, subtract the previous
position to get the difference.
Repeat that thousands of times with different passwords, and record the
WAL record size of each attempt. The smaller the WAL size, the more
common characters that guess had with the victim password.
The passwords are (usually) stored as MD5 hashes, but the procedure
works with those too. Each attempt will give a hint on how many common
bytes the attempt had with the victim hash.
There are some complications that make this difficult to perform in
practice. A regular user can't perform a checkpoint directly, she'll
have to generate a lot of other activity to trigger one, or wait until
one happens naturally. The measurement of the WAL record size might be
conflated by other concurrent activity that wrote WAL. And you cannot
force your own pg_authid row to the same page as that of a chosen victim
- so you're limited to guessing victims that happen to be on the same page.
All in all, this is a bit clumsy and very time-consuming to pull off in
practice, but it's possible at least if the conditions are just right.
What should we do about this? Make it configurable on a per-table basis?
Disable FPW compression on system tables? Disable FPW on tables you
don't have SELECT access to? Add a warning to the docs?
- Heikki
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
* Heikki Linnakangas (hlinnaka@iki.fi) wrote:
What should we do about this? Make it configurable on a per-table
basis? Disable FPW compression on system tables? Disable FPW on
tables you don't have SELECT access to? Add a warning to the docs?
REVOKE EXECUTE ON FUNCTION pg_current_xlog_insert_location() FROM public;
Thanks,
Stephen
On 04/09/2015 06:28 PM, Stephen Frost wrote:
* Heikki Linnakangas (hlinnaka@iki.fi) wrote:
What should we do about this? Make it configurable on a per-table
basis? Disable FPW compression on system tables? Disable FPW on
tables you don't have SELECT access to? Add a warning to the docs?REVOKE EXECUTE ON FUNCTION pg_current_xlog_insert_location() FROM public;
Yeah, that's one option. Will also have to revoke access to
pg_stat_replication and anything else that might indirectly give away
the current WAL position.
- Heikki
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
* Heikki Linnakangas (hlinnaka@iki.fi) wrote:
On 04/09/2015 06:28 PM, Stephen Frost wrote:
* Heikki Linnakangas (hlinnaka@iki.fi) wrote:
What should we do about this? Make it configurable on a per-table
basis? Disable FPW compression on system tables? Disable FPW on
tables you don't have SELECT access to? Add a warning to the docs?REVOKE EXECUTE ON FUNCTION pg_current_xlog_insert_location() FROM public;
Yeah, that's one option. Will also have to revoke access to
pg_stat_replication and anything else that might indirectly give
away the current WAL position.
Sure, though pg_stat_replication already only returns the PID and no
details, unless you're a superuser.
Thanks,
Stephen
On Fri, Apr 10, 2015 at 1:07 AM, Stephen Frost <sfrost@snowman.net> wrote:
* Heikki Linnakangas (hlinnaka@iki.fi) wrote:
On 04/09/2015 06:28 PM, Stephen Frost wrote:
* Heikki Linnakangas (hlinnaka@iki.fi) wrote:
What should we do about this? Make it configurable on a per-table
basis? Disable FPW compression on system tables? Disable FPW on
tables you don't have SELECT access to? Add a warning to the docs?REVOKE EXECUTE ON FUNCTION pg_current_xlog_insert_location() FROM public;
Yeah, that's one option. Will also have to revoke access to
pg_stat_replication and anything else that might indirectly give
away the current WAL position.Sure, though pg_stat_replication already only returns the PID and no
details, unless you're a superuser.
For consistency we may want to have the same behavior for
pg_current_xlog_insert_location(), pg_last_xlog_receive_location(),
pg_current_xlog_location() and pg_last_xlog_replay_location().
--
Michael
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Apr 9, 2015, at 8:51 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
What should we do about this?
I bet that there are at least 1000 covert channel attacks that are more practically exploitable than this. When this is anywhere near the top of the list of things to worry about, I recommend we throw a huge party and then fly home in our faster-than-light starships which, by then, will probably be available at Walmart.
...Robert
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 04/10/2015 05:17 AM, Robert Haas wrote:
On Apr 9, 2015, at 8:51 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
What should we do about this?
I bet that there are at least 1000 covert channel attacks that are more practically exploitable than this.
Care to name some? This is certainly quite cumbersome to exploit, but
it's doable.
We've talked a lot about covert channels and timing attacks on RLS, but
this makes me more worried because you can attack passwords stored in
pg_authid.
- Heikki
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Mon, Apr 13, 2015 at 9:38 AM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
On 04/10/2015 05:17 AM, Robert Haas wrote:
On Apr 9, 2015, at 8:51 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
What should we do about this?
I bet that there are at least 1000 covert channel attacks that are more
practically exploitable than this.Care to name some? This is certainly quite cumbersome to exploit, but it's
doable.We've talked a lot about covert channels and timing attacks on RLS, but this
makes me more worried because you can attack passwords stored in pg_authid.
Isn't the attack mentioned on this thread true as long as a user knows
that a given table stores a password? I don't see why this would be
limited to pg_authid.
--
Michael
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Thu, Apr 9, 2015 at 8:51 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
All in all, this is a bit clumsy and very time-consuming to pull off in
practice, but it's possible at least if the conditions are just right.
What should we do about this? Make it configurable on a per-table basis?
I think making it configurable on a per-table basis have another advantage
of controlling impact of FPW compression for tables that have less
compressible data (there is a CPU overhead of compression even though
it doesn't actually compress much). In-fact I had added such an option
during development of another related patch (WAL compression for Update),
if we think it is useful, I can extract that part of the patch and rebase
it.
With Regards,
Amit Kapila.
EnterpriseDB: http://www.enterprisedb.com
* Heikki Linnakangas (hlinnaka@iki.fi) wrote:
On 04/10/2015 05:17 AM, Robert Haas wrote:
On Apr 9, 2015, at 8:51 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
What should we do about this?
I bet that there are at least 1000 covert channel attacks that are more practically exploitable than this.
Care to name some? This is certainly quite cumbersome to exploit,
but it's doable.
I don't see any good reason to expose this information to every user on
the system, regardless of how easy (or not easy) it is to exploit.
There's a bunch of information which we want monitoring systems to be
able to gather but which shouldn't be generally available and this is
just another example of that.
Thanks,
Stephen
On Sun, Apr 12, 2015 at 8:38 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
Care to name some? This is certainly quite cumbersome to exploit, but it's
doable.We've talked a lot about covert channels and timing attacks on RLS, but this
makes me more worried because you can attack passwords stored in pg_authid.
Well, one thing to think about is that, if we're going to take this
kind of attack seriously, it could be used on user data, too. I mean,
you've just got to be able to get a row into the same block as the row
you want to find out something about, and there's no reason that need
be true only for pg_authid. And, even if you ban access to
information on the pg_xlog insert location, what's to prevent someone
from gleaning similar information via a timing attack on the
compression itself? You can even get some information from figuring
out, by trial and error, how much you need to expand a row to get it
to spill over into another block. If there happens to be enough
free-space on the page where the row is located to allow a HOT update,
you can repeatedly update it until it gets moved to some unrelated
page. Granted, knowing the length of an unseen row isn't as good as
knowing the contents, but it's still potentially useful information.
As to RLS - yeah, that's where I think a lot of the possible covert
channel attacks are. But it doesn't have to be RLS per se. It can
be, for example, a table some of whose contents you expose via a
security barrier view. It can be a security-definer function that you
call and it returns some data that you don't have rights to view
directly. Basically, it can be any table to which you have some
access, but not complete access. Then you can use timing attacks,
scrutinize EXPLAIN plans for clues, look at CTIDs, and so on.
Basically, I'm worried that it's going to be completely impractical to
prevent a certain amount of information leakage when you have partial
access to a table, and that in a largely-futile effort to try to
prevent it, we'll end up making a whole bunch of things (like the WAL
insert position) super-user only, and that this will in fact be a net
reduction in security because it'll encourage people to use the
superuser account more.
Perhaps that concern is ill-founded, but that's what I'm worried about.
--
Robert Haas
EnterpriseDB: http://www.enterprisedb.com
The Enterprise PostgreSQL Company
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 04/14/2015 05:42 AM, Robert Haas wrote:
On Sun, Apr 12, 2015 at 8:38 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
Care to name some? This is certainly quite cumbersome to exploit, but it's
doable.We've talked a lot about covert channels and timing attacks on RLS, but this
makes me more worried because you can attack passwords stored in pg_authid.Well, one thing to think about is that, if we're going to take this
kind of attack seriously, it could be used on user data, too. I mean,
you've just got to be able to get a row into the same block as the row
you want to find out something about, and there's no reason that need
be true only for pg_authid.
Sure.
And, even if you ban access to information on the pg_xlog insert
location, what's to prevent someone from gleaning similar information
via a timing attack on the compression itself?
Yep, that's another vector. Even more fiddly than the record size, but
nevertheless.
You can even get some information from figuring
out, by trial and error, how much you need to expand a row to get it
to spill over into another block. If there happens to be enough
free-space on the page where the row is located to allow a HOT update,
you can repeatedly update it until it gets moved to some unrelated
page. Granted, knowing the length of an unseen row isn't as good as
knowing the contents, but it's still potentially useful information.
True as well. That's not an issue for the MD5 hashes stored in
pg_authid, they all have the same length, but it can be for application
data.
As to RLS - yeah, that's where I think a lot of the possible covert
channel attacks are. But it doesn't have to be RLS per se. It can
be, for example, a table some of whose contents you expose via a
security barrier view. It can be a security-definer function that you
call and it returns some data that you don't have rights to view
directly. Basically, it can be any table to which you have some
access, but not complete access. Then you can use timing attacks,
scrutinize EXPLAIN plans for clues, look at CTIDs, and so on.Basically, I'm worried that it's going to be completely impractical to
prevent a certain amount of information leakage when you have partial
access to a table, and that in a largely-futile effort to try to
prevent it, we'll end up making a whole bunch of things (like the WAL
insert position) super-user only, and that this will in fact be a net
reduction in security because it'll encourage people to use the
superuser account more.Perhaps that concern is ill-founded, but that's what I'm worried about.
I'm not a big fan of locking down WAL position information either. If we
have to treat the current WAL position is security-sensitive
information, we're doing something wrong.
But I don't want to just give up either. One option is to make this
controllable on a per-table basis, as Amit suggested. Then we could
always disable it for pg_authid, add a suitable warning to the docs, and
let the DBA enable/disable it for other tables. It's a bit of a cop-out,
but would fix the immediate problem.
- Heikki
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Tue, Apr 14, 2015 at 4:50 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
On 04/14/2015 05:42 AM, Robert Haas wrote:
On Sun, Apr 12, 2015 at 8:38 PM, Heikki Linnakangas <hlinnaka@iki.fi>
wrote:As to RLS - yeah, that's where I think a lot of the possible covert
channel attacks are. But it doesn't have to be RLS per se. It can
be, for example, a table some of whose contents you expose via a
security barrier view. It can be a security-definer function that you
call and it returns some data that you don't have rights to view
directly. Basically, it can be any table to which you have some
access, but not complete access. Then you can use timing attacks,
scrutinize EXPLAIN plans for clues, look at CTIDs, and so on.Basically, I'm worried that it's going to be completely impractical to
prevent a certain amount of information leakage when you have partial
access to a table, and that in a largely-futile effort to try to
prevent it, we'll end up making a whole bunch of things (like the WAL
insert position) super-user only, and that this will in fact be a net
reduction in security because it'll encourage people to use the
superuser account more.Perhaps that concern is ill-founded, but that's what I'm worried about.
I'm not a big fan of locking down WAL position information either. If we
have to treat the current WAL position is security-sensitive information,
we're doing something wrong.But I don't want to just give up either. One option is to make this
controllable on a per-table basis, as Amit suggested. Then we could always
disable it for pg_authid, add a suitable warning to the docs, and let the
DBA enable/disable it for other tables. It's a bit of a cop-out, but would
fix the immediate problem.
I think it's a fairly narrow attack vector. As long as we document it
clearly, and make it easy enough to turn it off, I think that's definitely
enough. Most people will not care at all, I'm sure - but we need to cater
to those that do.
I think we could probably even get away with just documenting the risk and
having people turn off the compression *completely* if they care about it,
but if we can do it at a table level, that's obviously a lot better.
--
Magnus Hagander
Me: http://www.hagander.net/
Work: http://www.redpill-linpro.com/
* Magnus Hagander (magnus@hagander.net) wrote:
On Tue, Apr 14, 2015 at 4:50 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
I'm not a big fan of locking down WAL position information either. If we
have to treat the current WAL position is security-sensitive information,
we're doing something wrong.
I really don't see the downside to limiting who can see that
information. I meant to mention it in my email last night with the
patch allowing the GRANT system to work for other functions, but I added
the functions suggested by Michael to the list of ones which don't have
the default ACL of 'execute to PUBLIC' to that set.
But I don't want to just give up either. One option is to make this
controllable on a per-table basis, as Amit suggested. Then we could always
disable it for pg_authid, add a suitable warning to the docs, and let the
DBA enable/disable it for other tables. It's a bit of a cop-out, but would
fix the immediate problem.I think it's a fairly narrow attack vector. As long as we document it
clearly, and make it easy enough to turn it off, I think that's definitely
enough. Most people will not care at all, I'm sure - but we need to cater
to those that do.
I agree that it's something to document, but I don't think it's sensible
to have the default be "at risk". That said, as long as there's a way
to restrict access to these functions (without having to fight with the
system on upgrades, etc, to have that be preserved..) then I'm not going
to push too hard about the default. We need a proper "hardening"
guide anyway, this would just need to be included in that documentation.
I think we could probably even get away with just documenting the risk and
having people turn off the compression *completely* if they care about it,
but if we can do it at a table level, that's obviously a lot better.
I *really* don't like the idea that the "fix" for such an information
disclosure risk is to completely disable an extremely useful feature.
In fact, I find the suggestion of it rather ridiculous.
I do like the idea of being able to control this on a per-table basis
as that's a useful feature, but that's completely independent from this
concern.
Thanks!
Stephen
On Wed, Apr 15, 2015 at 12:00 AM, Magnus Hagander <magnus@hagander.net> wrote:
On Tue, Apr 14, 2015 at 4:50 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
On 04/14/2015 05:42 AM, Robert Haas wrote:
On Sun, Apr 12, 2015 at 8:38 PM, Heikki Linnakangas <hlinnaka@iki.fi>
wrote:As to RLS - yeah, that's where I think a lot of the possible covert
channel attacks are. But it doesn't have to be RLS per se. It can
be, for example, a table some of whose contents you expose via a
security barrier view. It can be a security-definer function that you
call and it returns some data that you don't have rights to view
directly. Basically, it can be any table to which you have some
access, but not complete access. Then you can use timing attacks,
scrutinize EXPLAIN plans for clues, look at CTIDs, and so on.Basically, I'm worried that it's going to be completely impractical to
prevent a certain amount of information leakage when you have partial
access to a table, and that in a largely-futile effort to try to
prevent it, we'll end up making a whole bunch of things (like the WAL
insert position) super-user only, and that this will in fact be a net
reduction in security because it'll encourage people to use the
superuser account more.Perhaps that concern is ill-founded, but that's what I'm worried about.
I'm not a big fan of locking down WAL position information either. If we
have to treat the current WAL position is security-sensitive information,
we're doing something wrong.But I don't want to just give up either. One option is to make this
controllable on a per-table basis, as Amit suggested. Then we could always
disable it for pg_authid, add a suitable warning to the docs, and let the
DBA enable/disable it for other tables. It's a bit of a cop-out, but would
fix the immediate problem.I think it's a fairly narrow attack vector. As long as we document it
clearly, and make it easy enough to turn it off, I think that's definitely
enough. Most people will not care at all, I'm sure - but we need to cater to
those that do.I think we could probably even get away with just documenting the risk and
having people turn off the compression *completely* if they care about it,
but if we can do it at a table level, that's obviously a lot better.
+1
Regards,
--
Fujii Masao
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Apr 15, 2015 at 11:10 AM, Fujii Masao <masao.fujii@gmail.com> wrote:
On Wed, Apr 15, 2015 at 12:00 AM, Magnus Hagander <magnus@hagander.net> wrote:
On Tue, Apr 14, 2015 at 4:50 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
On 04/14/2015 05:42 AM, Robert Haas wrote:
On Sun, Apr 12, 2015 at 8:38 PM, Heikki Linnakangas <hlinnaka@iki.fi>
wrote:As to RLS - yeah, that's where I think a lot of the possible covert
channel attacks are. But it doesn't have to be RLS per se. It can
be, for example, a table some of whose contents you expose via a
security barrier view. It can be a security-definer function that you
call and it returns some data that you don't have rights to view
directly. Basically, it can be any table to which you have some
access, but not complete access. Then you can use timing attacks,
scrutinize EXPLAIN plans for clues, look at CTIDs, and so on.Basically, I'm worried that it's going to be completely impractical to
prevent a certain amount of information leakage when you have partial
access to a table, and that in a largely-futile effort to try to
prevent it, we'll end up making a whole bunch of things (like the WAL
insert position) super-user only, and that this will in fact be a net
reduction in security because it'll encourage people to use the
superuser account more.Perhaps that concern is ill-founded, but that's what I'm worried about.
I'm not a big fan of locking down WAL position information either. If we
have to treat the current WAL position is security-sensitive information,
we're doing something wrong.But I don't want to just give up either. One option is to make this
controllable on a per-table basis, as Amit suggested. Then we could always
disable it for pg_authid, add a suitable warning to the docs, and let the
DBA enable/disable it for other tables. It's a bit of a cop-out, but would
fix the immediate problem.I think it's a fairly narrow attack vector. As long as we document it
clearly, and make it easy enough to turn it off, I think that's definitely
enough. Most people will not care at all, I'm sure - but we need to cater to
those that do.I think we could probably even get away with just documenting the risk and
having people turn off the compression *completely* if they care about it,
but if we can do it at a table level, that's obviously a lot better.+1
OK. I am fine to implement anything required here if needed, meaning
the following:
1) Doc patch to mention that it is possible that compression can give
hints to attackers when working on sensible fields that have a
non-fixed size.
2) Switch at relation level to control wal_compression. This needs to
change XLogRecordAssemble by adding some new logic to check if a
relation is enforcing WAL compression or not. As a reloption, there
are three possible values: true, false and fallback to system default.
Also, I think that we should simply extend XLogRegisterBuffer() and
pass to it the reloption flag that is then registered in
registered_buffer, and XLogRecordAssemble() decides with this flag if
block is compressed or not. Do we want to add this reloption switch to
indexes as well? Or only tables? For indexes things will get heavier
as we would need to add a parameter for all the index types.
Regards,
--
Michael
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Apr 15, 2015 at 11:55 AM, Michael Paquier wrote:
OK. I am fine to implement anything required here if needed, meaning
the following:
1) Doc patch to mention that it is possible that compression can give
hints to attackers when working on sensible fields that have a
non-fixed size.
2) Switch at relation level to control wal_compression. This needs to
change XLogRecordAssemble by adding some new logic to check if a
relation is enforcing WAL compression or not. As a reloption, there
are three possible values: true, false and fallback to system default.
Also, I think that we should simply extend XLogRegisterBuffer() and
pass to it the reloption flag that is then registered in
registered_buffer, and XLogRecordAssemble() decides with this flag if
block is compressed or not. Do we want to add this reloption switch to
indexes as well? Or only tables? For indexes things will get heavier
as we would need to add a parameter for all the index types.
After looking at reloptions.c, what we are going to need as well is a
new relopt_type, like RELOPT_TYPE_ENUM for this purpose to be able to
define the 'default' value. We could as well have things using
RELOPT_TYPE_STRING. Any input on this matter is welcome.
--
Michael
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Apr 15, 2015 at 12:15 AM, Stephen Frost wrote:
We need a proper "hardening"
guide anyway, this would just need to be included in that documentation.
+1. I am sure that many users would like a hardening manual in the
official documentation.
--
Michael
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On Wed, Apr 15, 2015 at 11:55 AM, Michael Paquier
<michael.paquier@gmail.com> wrote:
On Wed, Apr 15, 2015 at 11:10 AM, Fujii Masao <masao.fujii@gmail.com> wrote:
On Wed, Apr 15, 2015 at 12:00 AM, Magnus Hagander <magnus@hagander.net> wrote:
On Tue, Apr 14, 2015 at 4:50 PM, Heikki Linnakangas <hlinnaka@iki.fi> wrote:
On 04/14/2015 05:42 AM, Robert Haas wrote:
On Sun, Apr 12, 2015 at 8:38 PM, Heikki Linnakangas <hlinnaka@iki.fi>
wrote:As to RLS - yeah, that's where I think a lot of the possible covert
channel attacks are. But it doesn't have to be RLS per se. It can
be, for example, a table some of whose contents you expose via a
security barrier view. It can be a security-definer function that you
call and it returns some data that you don't have rights to view
directly. Basically, it can be any table to which you have some
access, but not complete access. Then you can use timing attacks,
scrutinize EXPLAIN plans for clues, look at CTIDs, and so on.Basically, I'm worried that it's going to be completely impractical to
prevent a certain amount of information leakage when you have partial
access to a table, and that in a largely-futile effort to try to
prevent it, we'll end up making a whole bunch of things (like the WAL
insert position) super-user only, and that this will in fact be a net
reduction in security because it'll encourage people to use the
superuser account more.Perhaps that concern is ill-founded, but that's what I'm worried about.
I'm not a big fan of locking down WAL position information either. If we
have to treat the current WAL position is security-sensitive information,
we're doing something wrong.But I don't want to just give up either. One option is to make this
controllable on a per-table basis, as Amit suggested. Then we could always
disable it for pg_authid, add a suitable warning to the docs, and let the
DBA enable/disable it for other tables. It's a bit of a cop-out, but would
fix the immediate problem.I think it's a fairly narrow attack vector. As long as we document it
clearly, and make it easy enough to turn it off, I think that's definitely
enough. Most people will not care at all, I'm sure - but we need to cater to
those that do.I think we could probably even get away with just documenting the risk and
having people turn off the compression *completely* if they care about it,
but if we can do it at a table level, that's obviously a lot better.+1
OK. I am fine to implement anything required here if needed, meaning
the following:
1) Doc patch to mention that it is possible that compression can give
hints to attackers when working on sensible fields that have a
non-fixed size.
I think that this patch is enough as the first step.
2) Switch at relation level to control wal_compression.
ALTER TABLE SET is not allowed on system catalog like pg_authid. So should we
change it so that a user can change the flag even on system catalog? I'm afraid
that the change might cause another problem, though. Probably we can disable
the compression on every system catalogs by default. But I can imagine that
someone wants to enable the compression even on system catalog. For example,
pg_largeobject may cause lots of FPW.
This needs to
change XLogRecordAssemble by adding some new logic to check if a
relation is enforcing WAL compression or not. As a reloption, there
are three possible values: true, false and fallback to system default.
Also, I think that we should simply extend XLogRegisterBuffer() and
pass to it the reloption flag that is then registered in
registered_buffer, and XLogRecordAssemble() decides with this flag if
block is compressed or not. Do we want to add this reloption switch to
indexes as well?
Maybe.
Regards,
--
Fujii Masao
--
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers
On 04/10/2015 05:17 AM, Robert Haas wrote:
I bet that there are at least 1000 covert channel attacks that are
more practically exploitable than this. When this is anywhere near
the top of the list of things to worry about, I recommend we throw a
huge party and then fly home in our faster-than-light starships
which, by then, will probably be available at Walmart.
Let's try to put some perspective on how serious (or not) this leak is.
I'm going to use finding a password hash in pg_authid as the target.
After each checkpoint, we can make one "guess", and see how that
compresses. If we assume ideal conditions, and guess one hex digit at a
time (the md5 hashes are stored as hex strings), you can find a 32 digit
hash in 16*32 = 512 checkpoints. You could possible improve on that, by
doing a binary search of the digits: first use a "guess" that contains
digits 0-8, then 9-f, and find which range the victim was in. The split
that range in two, repeat, until you find the digit. With that method,
the theoretical minimum is log2(16)*32 = 128 checkpoints.
Obviously, the real world is more complicated and you won't get very
close to that ideal case.
For my entertainment, I wrote a little exploit script (attached). I
didn't use the binary-search approach, it guesses one digit at a time.
Testing on my laptop, in a newly initdb'd database with no other
activity, it found a full MD5 hash in 3594 checkpoints. I cheated to
make it faster, and used the CHECKPOINT command instead of waiting or
writing a lot of WAL, to trigger the checkpoints, but that shouldn't
affect the number of checkpoints required. Your mileage may vary, of
course, and I'm sure this script will get confused and not work in many
cases, but OTOH I'm sure you could also optimize it further.
If we take that ~4000 checkpoints figure, and checkpoint_timeout=5
minutes, it would take about two weeks. But if you're happy with getting
just the first 4 or 8 bytes or so, and launch a dictionary attack on
that, you can stop much earlier than that.
- Heikki