Páginas

quinta-feira, 9 de abril de 2026

PostgreSQL Security: The Practical Guide to Preventing Memory Leaks & Code Execution (No Fluff)

 


On April 8, 2026, Debian released DLA-4524-1 fixing four PostgreSQL 13 vulnerabilities (CVE-2026-2003 through CVE-2026-2006). But if you only read the advisory, you'll be repeating the same panic next month.


PostgreSQL is the world’s most advanced open-source database. But like any complex software, it has bugs. Recently, the Debian LTS team released a fix for four vulnerabilities (CVE-2026-2003 through CVE-2026-2006) affecting PostgreSQL 13.

Here’s the reality: A new CVE is published every few hours. If you only react to each one as “news,” you’ll always be behind. The goal is to build a repeatable process for checking, fixing, and mitigating—whether it’s April 2026 or April 2028.

Below, I’ll show you exactly how to:


1. Check if your systems are vulnerable (actual commands).

2. Fix it with an automation script.

3. Mitigate if you can’t update right now.

4. Learn by building a safe test lab.


How to check if you are vulnerable (No guesswork)


These four CVEs affect PostgreSQL 13 (specifically versions prior to 13.23-0+deb11u2 on Debian 11). Other distributions have their own version numbers.

Run these commands as root or with sudo:


Ubuntu 22.04 / 24.04 (using apt)

bash
# Check installed version
dpkg -l | grep postgresql-13

# Or use apt policy
apt policy postgresql-13

# If the version is less than 13.23-0+deb11u2 (or an equivalent backport), you're vulnerable.


Rocky Linux / AlmaLinux 8/9 (using dnf)

bash
# Check installed version
rpm -q postgresql13-server

# Query the available update from upstream
dnf check-update postgresql13-server

# Vulnerable versions: anything before 13.23-1 (check your distro's backport)


SUSE Linux Enterprise / openSUSE (using zypper)

bash
# Check installed version
zypper info postgresql13-server

# See if patch is available
zypper list-patches | grep postgresql

What you’re looking for:

If your postgresql-13 package version is older than 13.23 (e.g., 13.11, 13.18, 13.22), you are vulnerable to all four CVEs:

CVE-2026-2003 – Memory leak via oidvector type.

CVE-2026-2004 – Arbitrary code execution via intarray extension.

CVE-2026-2005 – Heap buffer overflow in pgcrypto.

CVE-2026-2006 – Buffer overrun via multibyte character length.


Automation script to apply the fix (Bash – works on all major distros)

Save this as fix-postgres.sh and run it. It detects your distro and applies the update automatically.

bash
#!/bin/bash
# postgres-security-fixer.sh – checks and patches CVE-2026-2003 through -2006

set -e

echo "[*] Detecting OS distribution..."
if [ -f /etc/os-release ]; then
    . /etc/os-release
    OS=$ID
    VER=$VERSION_ID
else
    echo "Cannot detect OS. Exiting."
    exit 1
fi

case $OS in
    ubuntu|debian)
        echo "[+] Updating package list..."
        sudo apt update
        echo "[+] Upgrading postgresql-13..."
        sudo apt install --only-upgrade postgresql-13 -y
        ;;
    rocky|almalinux|rhel)
        echo "[+] Checking and updating PostgreSQL 13..."
        sudo dnf update postgresql13-server -y
        ;;
    suse|opensuse-leap|opensuse-tumbleweed)
        echo "[+] Updating PostgreSQL 13..."
        sudo zypper patch --cve="CVE-2026-2003,CVE-2026-2004,CVE-2026-2005,CVE-2026-2006" -y
        ;;
    *)
        echo "Unsupported OS: $OS"
        exit 1
        ;;
esac

echo "[*] Restarting PostgreSQL service..."
sudo systemctl restart postgresql

echo "[*] Verifying new version..."
psql --version

echo "[✓] Done. Your PostgreSQL is now patched."


Make it executable: chmod +x fix-postgres.sh && ./fix-postgres.sh

Alternative mitigation if you can’t update now (No patch? No problem.)

Sometimes you cannot restart the database or apply an update immediately. Here are three layered mitigations that buy you time.

1. Block the dangerous extensions (intarray & pgcrypto)

The worst CVEs (CVE-2026-2004 and CVE-2026-2005) require the intarray and pgcrypto extensions to be installed and used by an attacker.
sql
-- As a PostgreSQL superuser, revoke public usage from these extensions
REVOKE ALL ON EXTENSION intarray FROM PUBLIC;
REVOKE ALL ON EXTENSION pgcrypto FROM PUBLIC;

-- Drop them entirely if you don't need them
DROP EXTENSION IF EXISTS intarray CASCADE;
DROP EXTENSION IF EXISTS pgcrypto CASCADE;


2. Network-level blocking with iptables (if only trusted apps connect)

If your app servers are on the same network, restrict database port (5432) to only those IPs:

bash
# Allow only 192.168.1.100 (your app server)
sudo iptables -A INPUT -p tcp --dport 5432 -s 192.168.1.100 -j ACCEPT
# Block everyone else
sudo iptables -A INPUT -p tcp --dport 5432 -j DROP


3. AppArmor profile to restrict PostgreSQL process

On Ubuntu / Debian, enforce a profile that prevents arbitrary code execution:

bash
sudo aa-enforce /usr/lib/postgresql/13/bin/postgres
sudo aa-status | grep postgres


Suggested Reading


PostgreSQL: Up and Running, 4th Edition" by Regina Obe & Leo Hsu - Amazon


Why it’s relevant: Most DBAs know basic SQL but not operational security. This book dedicates two full chapters to:

- Extension security (exactly the intarray and pgcrypto risks).

- Hardening PostgreSQL against memory corruption attacks.

- Backup strategies before applying emergency patches.

Buying through this link supports my work – and gives you the exact knowledge to handle the next 10 CVEs without panic.


Hands-on Lab: Reproduce & test the fix safely


Do not test on production. Use a disposable environment.

Option 1: Docker (easiest)

bash
# Run a vulnerable container (example – adjust tag to a real vulnerable version)
docker run --name vuln-postgres -e POSTGRES_PASSWORD=test -d postgres:13.22

# Inside the container, attempt to exploit CVE-2026-2006 (multibyte overrun)
docker exec -it vuln-postgres psql -U postgres

# Now apply the fix by upgrading to 13.23+
docker stop vuln-postgres
docker run --name fixed-postgres -e POSTGRES_PASSWORD=test -d postgres:13.23


Option 2: Local VM with Vagrant

ruby
# Vagrantfile
Vagrant.configure("2") do |config|
  config.vm.box = "debian/bullseye64"
  config.vm.provision "shell", inline: <<-SHELL
    apt update
    apt install -y postgresql-13=13.22-0+deb11u1  # vulnerable version
    # Then run your test queries
  SHELL
end


What to test:

Try to cause a crash or memory leak by sending crafted intarray queries. The fixed version should reject them.








Nenhum comentário:

Postar um comentário