PostgreSQL Vulnerabilities: Types & How to Secure Against Them - TuxCare

php2shell patches (CVE-2026-109618 and CVE-2026-109619) for EOL PHP are out now. With sales replies slower than usual due to high demand, the fastest route to patched packages is to buy ELS for Runtimes online (opens in new tab). Read the patch FAQ

Go straight to an AI summary of this blog post instead

  • Summarize this post with Perplexity
  • Summarize this post with Gemini

Key Takeaways

  • PostgreSQL vulnerabilities cluster into four patterns: SQL injection, privilege escalation and code execution, broken access control, and backup tooling abuse.
  • The August 13, 2026 release closed 28 CVEs at once, half of them scored 8.8.
  • The bad outcome isn’t a leaked table, it’s an exploit chain that reaches the host OS.
  • Patch fast, trim privileges, bind your parameters, and don’t run an end-of-life version unpatched.
  • If you figured PostgreSQL’s built-in escaping functions had SQL injection solved, CVE-2025-1094 says otherwise.

PostgreSQL has a genuinely strong security track record, and like other widely deployed SQL databases it ships coordinated advisories on a predictable cadence, but several of the recent bugs have been ugly, and a few reach all the way to code execution on the host.

The 2026 advisories show no sign of the pace easing. February closed five CVEs, May closed eleven, and August 13 closed twenty-eight in a single coordinated release, with high-severity bugs landing across the core server, contrib modules, and client tooling. Here’s a rundown of the vulnerability types you’ll actually run into, what happens when you let them slide, and what closes the gap.

Types of PostgreSQL Vulnerabilities

A note on version ranges below: PostgreSQL’s advisories list the supported branches that were checked, which isn’t the same as a clean bill of health for everything older. Some of this code is shared across branches and some of it isn’t, so an EOL release like PostgreSQL 13 has to be assessed on its own rather than assumed vulnerable or assumed safe. What’s certain is that nobody upstream is doing that assessment for you anymore. TuxCare’s CVE Tracker is the quickest way to see what’s actually been triaged for an EOL version and whether a patch already exists through Endless Lifecycle Support.

postgresql-vulnerability-types-overview

SQL Injection

Still not dead, no matter how many ORMs promise otherwise. CVE-2025-1094, a high-severity SQL injection vulnerability found by Rapid7 and patched in February 2025, showed that even properly escaped input can turn into an injection under the wrong encoding conditions. The root issue was that libpq’s quoting functions (PQescapeLiteral, PQescapeIdentifier, PQescapeString and PQescapeStringConn) failed to neutralize quoting syntax in text that didn’t pass encoding validation. Same class of bug you’d find in a careless web app, just buried a layer deeper. And the fix itself broke those functions in a different way, leaving them ignoring their string length parameters and crashing some callers, which took another release a week later to sort out.

More recently, CVE-2026-6637 (CVSS 8.8) hit the refint contrib module with a stack buffer overflow that lets an unprivileged database user run arbitrary code as the operating system user running the database.

There’s a second, narrower attack in the same bug: if an application declares a user-controlled column as a refint cascade primary key, whoever supplies the update value for that key gets SQL injection. Both paths affect versions 14 through 18. CVE-2026-6638 adds an injection vector via table names in ALTER SUBSCRIPTION … REFRESH PUBLICATION, letting a subscriber-side table creator run SQL with the publication side’s credentials, though it’s far narrower in practice (CVSS 3.7, versions 16 through 18 only).

August brought another one worth knowing. CVE-2026-15741 (CVSS 8.8) is a SQL injection in EXTRACT() deparse where an object owner executes arbitrary SQL as a superuser through a hostile object definition, and it fires anywhere deparsed expressions get consumed, including pg_dump, psql commands like \sf, and non-core tools doing the same thing. The pattern is identical across all of them: input that should be inert ends up executable.

Watch out: CVE-2025-1094 has two distinct paths. For the libpq quoting functions, the risk kicks in when their output feeds into psql as input. For the command-line utilities, the specific trigger is a BIG5 client encoding combined with EUC_TW or MULE_INTERNAL on the server. If your stack mixes encodings or pipes query output into psql anywhere, patch the client.

Privilege Escalation and Remote Code Execution

The procedural language extensions are powerful, and that’s exactly what makes them worth attacking. CVE-2024-10979 (CVSS 8.8) let an unprivileged database user change sensitive process environment variables through PL/Perl, PATH among them, which is often all it takes to get arbitrary code execution even when the attacker has no operating system account on the box. It hit every branch from 12 through 17, so being on a recent version wasn’t a defense. PL/Perl came back around in August 2026 with CVE-2026-14670 (CVSS 8.8), a heap buffer overflow on the return of a tied hash that lets a function owner execute code as the database OS user through a crafted function body.

The February 2026 batch widened this category well beyond procedural languages. CVE-2026-2006 (CVSS 8.8) comes from missing multibyte character length validation in core text handling, where an ordinary database user issues crafted queries, overruns a buffer, and ends up executing code as the OS user. No extension required for that one. CVE-2026-2005 (CVSS 8.8) is a heap buffer overflow in pgcrypto reachable by anyone who can hand it ciphertext, which matters more than it sounds because pgcrypto is a trusted extension, meaning a non-superuser with CREATE privilege on the database can install it with CREATE EXTENSION. CVE-2026-2004 (CVSS 8.8) hits intarray through missing type validation on selectivity estimator input. Add CVE-2026-2007, a pg_trgm heap overflow at 8.2 affecting PostgreSQL 18, and that’s four high-severity bugs in a five-CVE release, three of them in contrib modules.

Worth noting that one CVSS score can cover more than one practical outcome. CVE-2026-6473 from the May batch is an 8.8 for an integer wraparound that lets an unprivileged database user undersize an allocation and write out of bounds. PostgreSQL says that may execute arbitrary code as the database OS user, while applications passing gigabyte-scale input into the affected functions may instead hand the input provider a segmentation fault. Reading the advisory beats reading the score.

The pattern across the serious ones is database-level access quietly becoming host-level access. The defensive posture is least privilege applied properly, which means restricting who can create functions and objects, dropping extensions your applications never touch, and keeping the exposed surface small. Just don’t mistake any of that for a substitute for patching, because none of it stops a memory-safety bug in core text handling.

Broken Access Control and Row Security Flaws

Not every bug announces itself. CVE-2024-10976 came from incomplete tracking of tables using row-level security, so a reused query plan could end up returning or modifying rows it had no business touching. It only affects databases actually using CREATE POLICY, which makes it easy to wave off until you remember which of your apps depend on that feature. CVE-2026-14666 is the August 2026 version of the same idea, where cached row-level security policies outlive changes to role membership, role attributes and database ownership, so a user keeps completing reads and writes that were permitted a moment ago and aren’t anymore.

CVE-2024-10978 belongs in this bucket too. An application using SET ROLE or SET SESSION AUTHORIZATION could have the wrong user ID apply to a query, letting a less-privileged user view or change rows meant for someone else. Not code execution, but exactly the sort of thing that quietly breaks a multi-tenant model. These are the quiet ones, application-specific and easy to miss because nothing crashes. The data just leaks out the side door.

CVE-2026-6478 (CVSS 6.5) is a different flavor again. A covert timing channel in the comparison of MD5-hashed passwords lets an attacker recover credentials good enough to authenticate. It doesn’t touch scram-sha-256, which has been the default in every supported release for a while now, but plenty of production databases still carry MD5 hashes inherited from an upgrade off PostgreSQL 13 or earlier. That’s the population actually at risk. Affects 14 through 18, patched in the May 2026 batch.

Backup and Restore Tooling

This one doesn’t fit the usual mental model of database vulnerabilities, which is exactly why it earns its own category.

CVE-2025-8714 and CVE-2025-8715 (both CVSS 8.8) came out of pg_dump in August 2025. CVE-2025-8714 lets a malicious superuser on the origin server plant psql meta-commands in the dump that execute as the client operating system account during a restore. CVE-2025-8715 does something similar through a newline in a purpose-crafted object name, and it’s arguably the worse of the two: it needs only a user of the origin server rather than a superuser, and the same attack can also achieve SQL injection as a superuser on the restore target. pg_dumpall, pg_restore and pg_upgrade are all in scope. CVE-2012-0868 had already fixed this class of bug once, and 11.20 quietly reintroduced it.

Then the fix needed a fix. CVE-2026-18408 (CVSS 8.8, August 2026) found another path through input expansion around the \restrict protection that was introduced for CVE-2025-8714, with \unrestrict on its own sufficient to make the original restore-time attack work again. The May batch had already added CVE-2026-6477 (CVSS 8.8), where a server superuser overwrites stack memory in psql or pg_dump through libpq’s lo_read().

CVE-2026-6475 (CVSS 8.8) extends the theme to pg_basebackup and pg_rewind, where symlink following lets an origin superuser overwrite unrelated local files, something like /var/lib/postgres/.bashrc, and hijack the operating system account. PostgreSQL scopes this one carefully, and so should you: starting the server after those commands already implicitly trusts the origin superuser through mechanisms like shared_preload_libraries, so the practical exposure sits in workflows that move, snapshot or otherwise act on the resulting files before the server comes up.

The thread running through this whole section is that the attack surface isn’t your application or your connection pool, it’s your backup job – something that often runs with elevated privileges and rarely gets the same scrutiny as the main database configuration. It’s also a reminder that a good number of these CVEs are client-side. PostgreSQL files them under the client component, and patching the server does nothing for them. The machines running psql, pg_dump, pg_basebackup and pg_createsubscriber need patching in their own right.

CVE Disclosed CVSS Component Impact Affects Patched Release
CVE-2026-18408 Aug 2026 8.8 psql and pg_dump \unrestrict reopens the CVE-2025-8714 restore attack 14-18 18.6, 17.11, 16.15, 15.19, 14.24
CVE-2026-15741 Aug 2026 8.8 core server SQL injection via EXTRACT() deparse 14-18 18.6, 17.11, 16.15, 15.19, 14.24
CVE-2026-14670 Aug 2026 8.8 core server (PL/Perl) Tied hash heap overflow executes arbitrary code 14-18 18.6, 17.11, 16.15, 15.19, 14.24
CVE-2026-14666 Aug 2026 4.2 core server Cached row security policies survive role changes 14-18 18.6, 17.11, 16.15, 15.19, 14.24
CVE-2026-6637 May 2026 8.8 refint contrib Stack buffer overflow plus a separate SQL injection path 14-18 18.4, 17.10, 16.14, 15.18, 14.23
CVE-2026-6477 May 2026 8.8 libpq, psql, pg_dump Server superuser overwrites client stack memory 14-18 18.4, 17.10, 16.14, 15.18, 14.23
CVE-2026-6475 May 2026 8.8 pg_basebackup, pg_rewind Arbitrary file overwrite via symlink following 14-18 18.4, 17.10, 16.14, 15.18, 14.23
CVE-2026-6473 May 2026 8.8 core server Out-of-bounds write, possible arbitrary code execution 14-18 18.4, 17.10, 16.14, 15.18, 14.23
CVE-2026-6478 May 2026 6.5 core server MD5 password hashes recoverable via timing channel 14-18 18.4, 17.10, 16.14, 15.18, 14.23
CVE-2026-6638 May 2026 3.7 core server SQL injection via REFRESH PUBLICATION table name 16-18 18.4, 17.10, 16.14
CVE-2026-2006 Feb 2026 8.8 core server Missing multibyte validation executes arbitrary code 14-18 18.2, 17.8, 16.12, 15.16, 14.21
CVE-2026-2005 Feb 2026 8.8 pgcrypto contrib Heap buffer overflow executes arbitrary code 14-18 18.2, 17.8, 16.12, 15.16, 14.21
CVE-2026-2004 Feb 2026 8.8 intarray contrib Missing type validation executes arbitrary code 14-18 18.2, 17.8, 16.12, 15.16, 14.21
CVE-2026-2007 Feb 2026 8.2 pg_trgm contrib Heap buffer overflow, privilege escalation not ruled out 18 18.2
CVE-2025-8715 Aug 2025 8.8 pg_dump and psql Newline in object name executes code and injects SQL 13-17 17.6, 16.10, 15.14, 14.19, 13.22
CVE-2025-8714 Aug 2025 8.8 pg_dump and psql Origin superuser executes arbitrary code on client 13-17 17.6, 16.10, 15.14, 14.19, 13.22
CVE-2025-1094 Feb 2025 8.1 core server, libpq quoting SQL injection via encoding validation bypass 13-17 17.3, 16.7, 15.11, 14.16, 13.19
CVE-2024-10979 Nov 2024 8.8 core server (PL/Perl) Environment variable changes execute arbitrary code 12-17 17.1, 16.5, 15.9, 14.14, 13.17, 12.21
CVE-2024-10978 Nov 2024 4.2 core server SET ROLE resets to the wrong user ID 12-17 17.1, 16.5, 15.9, 14.14, 13.17, 12.21
CVE-2024-10976 Nov 2024 4.2 core server Row security disregards user ID changes 12-17 17.1, 16.5, 15.9, 14.14, 13.17, 12.21

Risks of Not Securing PostgreSQL Vulnerabilities

This isn’t a “we’ll get to it next sprint” kind of decision. The downside runs from an awkward data leak all the way to a fully owned host.

postgresql-cve-exploit-chain-rce

A Breach That Costs Real Money

The 2026 IBM Cost of a Data Breach Report put the global average at USD 4.99 million, a record and a 12% jump on the year before, with detection, escalation and lost business driving most of the increase. The figure that should bother anyone running a slow patch cycle is the clock. Mean time to identify and contain a breach climbed to 247 days, reversing five straight years of improvement, and breaches that ran past the 200-day mark cost roughly a third more than the ones closed sooner.

Organizations running AI and automation across prevention, detection, investigation and response closed breaches about two months faster and paid USD 1.93 million less than the ones running none. All of which strengthens the case for pointing that automation at vulnerability management, the work of finding and closing holes before anybody walks through them.

Full Server Compromise, Not Just Data Loss

CVE-2025-1094 ties directly into the BeyondTrust vulnerability CVE-2024-12356, which was exploited as a zero-day in the high-profile attack on the U.S. Treasury Department. In every scenario Rapid7 tested, successfully exploiting the BeyondTrust flaw required exploiting CVE-2025-1094 to achieve remote code execution. Once someone is running shell commands on the database host, the database itself is the least of your worries – lateral movement across the rest of your Linux fleet becomes possible.

Teams running PostgreSQL bundled inside other products often don’t realize they’re exposed at all. PostgreSQL ships as a dependency inside a lot of third-party software, and when a CVE drops you can find yourself patching a database you’d forgotten you had.

Running an EOL Version With No Patches

postgresql-eol-patching-timeline-tuxcare-els

Once a major version hits end of life, upstream stops producing security fixes for it. New CVEs don’t stop getting discovered – they just stop getting fixed on that branch. Several of the 2026 bugs above affect every supported branch from 14 through 18, and the sting is that PostgreSQL 14 stops receiving fixes on November 12, 2026, so today’s supported version is next quarter’s problem. If you’re on PostgreSQL 13, you won’t see your version in the advisory and you won’t get a fix from upstream either way.

This is exactly what TuxCare’s Endless Lifecycle Support is built for. It backports CVE fixes for PostgreSQL 13 and applies them through your normal package manager, with PostgreSQL 14 coverage announced ahead of its EOL date, so you can stay patched now and move to a supported version whenever it actually fits your roadmap.

How to Secure Against PostgreSQL Vulnerabilities

Securing PostgreSQL is mostly discipline, not heroics. Three habits address a large share of the practical risk.

postgresql-security-checklist-best-practices

Patch Promptly and Track CVEs

PostgreSQL ships coordinated security releases across every supported branch at once. The November 2024 batch fixed CVE-2024-10979 and its siblings across 17.1, 16.5, 15.9, 14.14, 13.17 and 12.21 on the same day. The May 2026 batch landed eleven fixes in 18.4, 17.10, 16.14, 15.18 and 14.23 simultaneously, and August 13 shipped twenty-eight in 18.6, 17.11, 16.15, 15.19 and 14.24. Subscribe to the advisories and treat minor-version updates as routine maintenance rather than a project that needs a business case.

Pro tip: After a minor-version upgrade, run SELECT version(); in psql to confirm the server is really on the release you think it is. A package that upgraded cleanly but never got a service restart will happily keep reporting the old version. Then check the client side separately, because SELECT version() tells you nothing about psql, pg_dump, pg_basebackup or libpq on the machines that run them. One gotcha specific to PostgreSQL 18: 18.5 was never shipped after a regression turned up post-wrap, so the August release jumps straight from 18.4 to 18.6.

Restrict Privileges and Extension Creation

Plenty of PostgreSQL attack paths still run through database-level privileges, object-creation rights, or access to one particular extension, which is why least privilege keeps earning its keep. Limit who can create functions in PL/Perl and PL/Python, drop extensions nobody is using, and keep roles tight generally.

The recent bugs in refint, pgcrypto, intarray and pg_trgm are a decent argument for auditing that extension list this week rather than next quarter. Those restrictions would have closed the CVE-2024-10979 path and narrowed several others, but they won’t stop a memory-safety bug in core text handling, so they sit alongside patching rather than in place of it.

Validate Input and Use Parameterized Queries

Escaping is a backstop, not a strategy on its own. Use parameterized queries wherever values come from untrusted input, so that input never gets the chance to become executable SQL. For the parts of a statement that can’t be bound as parameters, meaning identifiers, table names, sort direction and anything else structural, allowlist strictly instead. Pair both with validation at the edge.

Best Practices to Prevent PostgreSQL Vulnerabilities

Those controls close individual attack paths. The next step is making the finding and the fixing systematic, so problems get caught and closed before anyone gets to exploit them.

Run Continuous Vulnerability Scanning

You can’t patch what you can’t see, and bundled PostgreSQL instances hide well, sometimes from the people running them. Scan continuously instead of quarterly, so a new CVE shows up on your radar in hours rather than at the next audit. When a scanner flags something, confirm it’s real before you scramble, because chasing a false positive burns time you don’t get back.

Automate Patching and Cover the Whole Stack

The slow part of patching usually isn’t finding the fix, it’s the maintenance window. Automated patching shrinks the gap between disclosure and deployment, which is the stretch where a known vulnerability stays exploitable even though a fix is already available. This is also where end-of-life coverage earns its keep, since TuxCare backports security fixes to supported EOL PostgreSQL releases along with covered direct and transitive dependencies, so an unsupported version keeps getting patched anyway.

Insider tip: Build your patch SLA around the CVE disclosure date, not the date somebody happened to notice it. Internet-facing vulnerabilities tend to start attracting scanning and exploitation attempts soon after a public advisory, so your clock should start when theirs does.

Harden Configuration and Monitor Logs

Defaults are a starting point, not a finished setup. Enforce TLS for client connections, and write pg_hba.conf rules that name the databases, roles, networks and authentication methods that genuinely need access rather than leaving broad entries sitting there. Remove or skip installing contrib extensions you aren’t using, and keep an eye on logs for odd SQL errors or repeated injection-style failures. Given how many of the recent bugs landed in contrib specifically, trimming that list is worth doing now rather than during the next scheduled review.

Secure PostgreSQL Against Vulnerability Exploits with TuxCare

PostgreSQL vulnerabilities are manageable, but only if you patch on time and don’t leave an end-of-life version in production without security coverage. PostgreSQL 13 passed its community end of life on November 13, 2025 and no longer gets official CVE fixes, and PostgreSQL 14 follows on November 12, 2026.

If either one is still in your stack, TuxCare’s Endless Lifecycle Support backports those fixes for you, applied through normal package-manager updates rather than a separate patching workflow, so you’re not stuck choosing between staying exposed and migrating on someone else’s deadline. Check where your PostgreSQL deployments actually stand first, then close the gaps in patch coverage.

Summary
PostgreSQL Vulnerabilities: Types & How to Secure Against Them
Article Name
PostgreSQL Vulnerabilities: Types & How to Secure Against Them
Description
Learn about PostgreSQL vulnerabilities, common attack methods, and best practices to secure your database from potential security threats.
Author
Publisher Name
TuxCare
Publisher Logo

Join 4,500+ Linux & Open Source Professionals!

2x a month. No spam.

Table of Contents
Get the open-source security answers you need

Join 4,500+ Linux & Open Source Professionals!

2x a month. No spam.