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