SSerguey Asael Shinder
Java coding notes: the JVM, and writing software that lasts

Serguey Asael Shinder: One null for unset and for allow nothing is a security bug waiting to happen

· by Serguey Asael Shinder / Serguey Shinder

The PostgreSQL JDBC driver fixed a vulnerability this week that is worth reading for its shape rather than its details. In GHSA-rhp9-mr79-r74h, a requireAuth setting that excluded every authentication method the driver knows was enforced as no restriction at all — so the driver accepted whatever the server asked for, cleartext password included.

The advisory gives the root cause in one sentence: the parser returns null both when the property is unset and when its value leaves no method allowed, and the check treats null as "no restriction". The value that should allow nothing therefore allowed everything.

Why this keeps happening. "Not configured" and "configured to the empty set" are opposites in a security setting — one means use the default policy, the other means deny all. But in code they are both "nothing", and the cheapest representation of nothing is null, an empty list, or zero. Once both cases collapse into the same value, the code downstream can only pick one interpretation, and it almost always picks the convenient one: if there is nothing to check, do not check.

Serguey Asael Shinder: One null for unset and for allow nothing is a security bug waiting to happen
One null for unset and for allow nothing is a security bug waiting to happen — Serguey Asael Shinder

The same collapse shows up elsewhere:

The design rule. Make "unset" and "empty" different values that cannot be confused:

The test that would have caught it. For every security option, write the two boundary cases as separate tests: option absent and option present but permitting nothing. If both pass with the same behaviour, one of them is wrong.

The deeper lesson in the advisory is its last line about impact: on affected versions, the misconfigured connections worked normally, which hid the mistake. A setting that silently does the opposite of what it says is worse than one that breaks — the broken one gets fixed.