CVE-2023-5868 - Understanding PostgreSQL’s Memory Disclosure Vulnerability
PostgreSQL, one of the world’s most popular open-source databases, faced a serious security risk in late 2023: CVE-2023-5868. This memory disclosure vulnerability let remote users access sensitive information directly from the PostgreSQL server. In this article, we’ll break down what CVE-2023-5868 is, demonstrate its exploitation with code samples, explain the dangers, and provide links for further reading.
What is CVE-2023-5868?
CVE-2023-5868 describes a vulnerability in PostgreSQL where certain aggregate function calls, using arguments of type 'unknown' (typically from string literals without an explicit type), let attackers read chunks of memory from the database backend. This flaw is due to excessive data output from aggregate function processing.
Normally, user-supplied data is carefully handled. However, PostgreSQL failed to sanitize memory returned when handling 'unknown'-type values, resulting in possible leaks of confidential information such as:
passwords or secrets present in memory.
Any authenticated user connecting over the network could potentially exploit the bug by crafting specific SQL queries.
How the Exploit Works
The heart of this vulnerability lies in improperly typed inputs. When you pass a string literal like 'foo' without a typecast, PostgreSQL treats its type as 'unknown'. Some aggregate functions, e.g., array_agg(), string_agg(), or even custom aggregates, do not fully initialize output memory. If these are called just right, they can over-read or leak data from memory previously used by the server.
Consider this query
SELECT array_agg(x)
FROM (VALUES ('foo'), ('bar'), ('baz')) AS t(x);
By default, this is fine. But the trick is that when you omit explicit types, the argument is handled as 'unknown' internally, and a flaw in aggregate processing would inadvertently return more data than intended.
Here's an exploit example, *based on reporting*
-- This query can leak memory contents
SELECT string_agg(x, ',')
FROM (VALUES ('aaa'), ('bbb')) AS t(x);
Suppose you remove quotes or type specifications, or use variations designed to confuse the parser
SELECT string_agg(x, ',')
FROM (VALUES ('aaa'::unknown), ('bbb'::unknown)) AS t(x);
Or even
-- Deliberately pass unknown-typed input
PREPARE leak_func AS
SELECT string_agg($1, ',') FROM generate_series(1, 2);
EXECUTE leak_func('test'); -- Input stays 'unknown'
In vulnerable versions, these queries can output corrupted or extra trailing bytes—often segments of whatever was left in memory in that area. That data *may* include sensitive fragments.
Real-World Impact
An attacker doesn’t need superuser rights; any normal user with the ability to run aggregate functions is potentially able to leak data this way. Since credentials and session data are often in memory, secrets might be exposed to a persistent attacker with access.
Fix and Mitigation
Upgrade immediately. The PostgreSQL team patched this issue in PostgreSQL 16.1, 15.5, 14.10, 13.13, and 12.17. All users should patch as soon as possible.
References
- PostgreSQL Security Advisory for CVE-2023-5868
- Official CVE Entry
- Security Release Notes
Conclusion
CVE-2023-5868 is a powerful reminder that small parsing oversights in major projects can have serious consequences. Even trusted user functions, when fed 'unknown' types, can accidentally spill secrets. Fix your databases promptly and always type your literals explicitly!
Keep your stack patched. Don’t take chances with memory leaks.
*Disclaimer: This article is intended for educational purposes only. Do not test or exploit vulnerabilities on systems you do not own or have permission to examine.*
Timeline
Published on: 12/10/2023 18:15:07 UTC
Last modified on: 12/11/2023 16:15:42 UTC