Jawaban langsung: CVE-2026-116241 membuat akun pgAdmin 4 biasa bisa menjalankan perintah sistem operasi di server pgAdmin lewat alat Import/Export Data. Skor CVSS 3.1 adalah 9.9. Hari ini, cek versi, cek siapa yang punya izin Import/Export Data, lalu update ke pgAdmin 4 v9.19.

Rilis 9.19 menutup 15 CVE sekaligus, CVE-2026-116238 sampai CVE-2026-116252. Satu di antaranya, CVE-2026-116238, membuat batas gagal login bisa dilewati. Menurut catatan CVE-2026-116241, perintah berjalan sebagai akun OS yang menjalankan pgAdmin.

Kondisi utama: Penyerang butuh 1 akun pgAdmin dengan izin Import/Export Data. Role User bawaan punya izin itu. Batas: Artikel ini tidak memuat isi query, payload, atau urutan serangan.

Kami membaca catatan CVE-2026-116241, catatan CVE-2026-116238, catatan rilis pgAdmin 4 v9.19, pengumuman rilis di postgresql.org, issue #10663, halaman image dpage/pgadmin4 di Docker Hub, dan CISA KEV pada 2 November 2026, pukul 06.35 sampai 07.40 WIB. Kami menguji 3 skrip di container podman dengan image resmi dpage/pgadmin4 9.18 dan 9.19, termasuk upgrade dengan volume yang sama. Jalur apt, dnf, pip, dan desktop kami tulis dari halaman download pgAdmin, tanpa uji.

Masalah: akun pgAdmin biasa bisa menjalankan perintah di server

Satu akun pgAdmin yang bocor atau satu karyawan yang tidak jujur bisa membuka jalan ke server pgAdmin.

pgAdmin 4 adalah alat admin PostgreSQL berbasis web. Banyak tim memasangnya di server dengan Docker, lalu membagi akun ke developer, analis, atau vendor. Akun biasa seharusnya hanya bisa bekerja di database yang dia punya. Celah ini membuat akun biasa bisa menjalankan perintah di host pgAdmin itu sendiri.

Menurut catatan CVE-2026-116241, CVE-2026-116241 adalah bypass dari perbaikan CVE-2026-17566. Alat yang sama juga menerima perbaikan CVE-2026-7816 di versi 9.15. Jadi pgAdmin 9.18 yang Anda pasang pada September tetap rentan.

Linimasa: 9.15 pada 11 Mei, 9.18 pada 17 September, issue placeholder 23 Oktober, rilis 9.19 pada 29 Oktober, 15 CVE terbit 30 Oktober, belum KEV per 2 November.
Titik abu-abu: perbaikan lama di alat yang sama. Titik teal: rilis aman. Titik merah: publikasi CVE. Titik amber: status saat artikel ini terbit. Sumber: CVE.org, catatan rilis pgAdmin, GitHub pgAdmin, Docker Hub, dan CISA KEV.

Data halaman image dpage/pgadmin4 di Docker Hub menunjukkan tag 9.19 dan latest terbit pada 29 Oktober 2026, pukul 15.29 UTC. Catatan CVE terbit pada 30 Oktober 2026, pukul 19.55 UTC, dari CNA PostgreSQL. Per 2 November 2026, halaman security pgAdmin belum menampilkan 15 CVE ini.

Cara kerja: 1 alat ekspor, perintah di host

Pemeriksaan query ekspor di pgAdmin dan parser psql membaca tanda kutip dengan cara berbeda.

Bagian ini memakai ringkasan resmi. Tujuannya membantu Anda memilih langkah yang tepat, bukan menjelaskan cara menyerang.

Ringkasan dari catatan CVE

Menurut catatan CVE-2026-116241, alat Import/Export Data membungkus query ekspor user dalam perintah \copy psql, lalu memeriksa query itu. Pemeriksaan itu menolak backslash di dalam string dengan kutip tunggal, tetapi tidak di dalam identifier dengan kutip ganda. Bila pengaturan database tertentu berubah, psql bisa menjalankan perintah di host pgAdmin sebelum server database menolak query.

Catatan CVE juga menulis 2 fakta penting. Role database biasa bisa mengubah pengaturan itu untuk dirinya sendiri. Izin Import/Export Data diberikan ke non-admin secara bawaan. Perbaikan di 9.19 menolak semua backslash di dalam identifier dengan kutip ganda.

Skor 15 CVE di rilis 9.19

Skor berbeda per versi CVSS, jadi tabel ini menulis keduanya. Semua skor berasal dari CNA PostgreSQL.

CVEAreaCVSS 3.1CVSS 4.0
CVE-2026-116241Alat Import/Export Data menjalankan perintah OS di host pgAdmin9.99.4
CVE-2026-116238Batas gagal login dan cek password bisa dilewati8.19.2
CVE-2026-116239Login LDAP atau Kerberos masuk ke akun lain dengan nama sama8.58.9
CVE-2026-116249Path berkas koneksi keluar dari folder storage user8.47.2
CVE-2026-116242, 116244, 116245, 116247SSH, Kerberos, service, dan berkas password memakai identitas akun layanan pgAdmin8.27.1
CVE-2026-116243Path binary utilitas bisa menunjuk ke shared storage7.57.7
CVE-2026-116248User biasa bisa membagi server ke semua user6.86.0
CVE-2026-116240, 116250, 116252, 116246File Manager, race symlink, refresh materialized view, dan password di environment6.57.0 sampai 7.3
CVE-2026-116251Sesi lain tetap hidup sesudah password berubah4.22.3
Tiga kartu: CVE-2026-116241 Import/Export Data skor 9.9, CVE-2026-116238 batas gagal login skor 9.2, dan 13 CVE lain. Versi aman: pgAdmin 4 v9.19.
(1) Kartu merah: 2 celah dengan skor tertinggi. (2) Kartu amber: 13 celah lain di rilis yang sama. (3) Panel amber: syarat serangan. (4) Kotak teal: versi aman. Sumber: catatan CVE dari CNA PostgreSQL dan catatan rilis pgAdmin 4 v9.19.

CVE-2026-116238 penting untuk server yang terbuka ke internet. Menurut catatan CVE-2026-116238, pgAdmin mengunci akun sesudah 3 kali gagal login, tetapi beberapa jalur login tidak menghitung percobaan. Akibatnya penyerang tanpa akun bisa menebak password tanpa batas, termasuk password admin.

Status eksploitasi per 2 November 2026

Kami tidak menemukan laporan serangan, kode eksploit publik di sumber resmi, atau entri CISA KEV. issue #10663 hanya berisi placeholder sampai rilis 9.19.

Analisa Rama Digital: halaman login pgAdmin menampilkan nomor versi kepada siapa pun, contoh ver=91800 untuk 9.18. Pemindai otomatis bisa menemukan server rentan dengan cepat. Jangan tunggu status KEV.

Siapa yang paling berisiko

Risiko bergantung pada siapa yang bisa login ke pgAdmin, bukan hanya pada versi.

Tabel ini merangkum catatan CVE-2026-116241, catatan CVE-2026-116238, dan catatan rilis pgAdmin 4 v9.19.

Kondisi pgAdminRisikoAlasan
Server mode terbuka ke internetTertinggiSiapa pun bisa mencoba login, dan batas gagal login bisa dilewati
Banyak akun non-admin: tim, magang, vendorTinggiRole User bawaan punya izin Import/Export Data
Login LDAP atau KerberosTinggiCVE-2026-116239 bisa membuat login masuk ke akun lain dengan nama sama
pgAdmin di host yang sama dengan database atau aplikasiPeriksaPerintah jalan sebagai akun OS pgAdmin, jadi rahasia di host ikut terbuka
1 admin, hanya lewat VPNPeriksaPenyerang butuh akun dulu, tetapi update tetap wajib
Desktop mode di laptopRendahHanya 1 pengguna lokal
Enam kartu risiko: server mode terbuka ke internet, banyak akun non-admin, dan login LDAP merah; host bersama database dan akses VPN amber; desktop mode abu-abu.
Kartu merah: banyak orang bisa login. Kartu amber: periksa konfigurasi. Kartu abu-abu: risiko rendah. Kotak bawah: cek versi dari luar. Sumber: catatan CVE, catatan rilis pgAdmin 4 v9.19, dan analisa Rama Digital.

Server pgAdmin sering menyimpan password database produksi. Satu host pgAdmin yang dikuasai bisa membuka semua database yang terdaftar di sana. Pola risiko yang sama ada di celah sertifikat LXD dan Incus CVE-2026-112816: alat admin yang memegang banyak server adalah aset dengan prioritas patch tertinggi.

Versi rentan dan versi aman

Semua versi pgAdmin 4 di bawah 9.19 rentan terhadap 15 CVE ini. Pakai tabel ini untuk menentukan langkah update menurut cara pasang.

Cara pasangStatus per 2 November 2026Naik ke
Image Docker dpage/pgadmin4Rentan sampai tag 9.18Tag 9.19, terbit 29 Oktober
Tag latestRentan bila ditarik sebelum 29 OktoberTarik ulang, lalu cek versi
Paket apt atau dnf dari repo pgAdminRentan di bawah 9.19Paket 9.19
Python wheel pgadmin4Rentan di bawah 9.19pgadmin4==9.19
Desktop Windows dan macOSRentan, risiko lebih rendah karena 1 penggunaInstaller 9.19
Belum bisa update hari iniRentanLangkah 4, lalu update secepatnya
Tabel 6 cara pasang: Docker sampai tag 9.18, tag latest lama, apt, dnf, pip, dan desktop rentan. Kotak bawah: 4 pengaturan server mode sebelum start pertama 9.19.
Merah: rentan, versi aman sudah ada. Amber: risiko lebih rendah atau langkah sementara. Kotak bawah: pengaturan yang berubah di 9.19. Sumber: catatan rilis pgAdmin 4 v9.19, Docker Hub, dan catatan CVE.

Data versi berasal dari catatan CVE-2026-116241, catatan rilis pgAdmin 4 v9.19, dan halaman image dpage/pgadmin4 di Docker Hub. Catatan CVE menulis rentang terdampak "before 9.19" untuk semua 15 CVE. Kami tidak menemukan backport ke cabang lama, jadi jangan tunggu versi 9.18.x.

Prasyarat sebelum mulai

  • Akses sudo atau akses Docker ke setiap server yang menjalankan pgAdmin.
  • Akun admin pgAdmin untuk membuka menu Users.
  • Daftar orang yang memang butuh akun pgAdmin. Contoh: admin database, developer, dan analis.
  • Backup volume atau folder /var/lib/pgadmin sebelum update.
  • Jendela maintenance 10 sampai 15 menit. Container dibuat ulang, jadi sesi aktif terputus.

Langkah 1: Cek versi pgAdmin

Simpan skrip ini sebagai cek-versi-pgadmin.sh. Skrip membaca versi dari container Docker atau Podman, paket apt atau dnf, berkas version.py, atau halaman login.

#!/usr/bin/env bash
# Cek versi pgAdmin 4 untuk CVE-2026-116241 dan 14 CVE lain di rilis 9.19.
# Pakai: sudo bash cek-versi-pgadmin.sh                    (container, paket, dan berkas di mesin ini)
#        bash cek-versi-pgadmin.sh --url https://ALAMAT-PGADMIN
#        bash cek-versi-pgadmin.sh 9.14 9.18 9.19            (versi yang Anda salin dari server lain)
AMAN=9.19

hasil() {
  if [ -z "$2" ]; then echo "$1: versi tidak terbaca"; return; fi
  if [ "$(printf '%s\n%s\n' "$AMAN" "$2" | sort -V | head -n1)" = "$AMAN" ]; then
    echo "$1: pgAdmin $2 -> AMAN (perbaikan ada sejak $AMAN)"
  else
    echo "$1: pgAdmin $2 -> RENTAN, update ke $AMAN atau lebih baru"
  fi
}

# Mode URL: halaman login memuat versi sebagai angka, contoh ver=91800 untuk 9.18.
if [ "$1" = "--url" ]; then
  ambil() { if command -v curl >/dev/null 2>&1; then curl -fsSL -m 10 "$1"; else wget -qO- -T 10 "$1"; fi; }
  angka=$(ambil "${2%/}/login" | grep -o 'ver=[0-9]*' | head -n1 | cut -d= -f2)
  if [ -z "$angka" ]; then echo "$2: versi tidak terbaca dari halaman login"; exit 1; fi
  hasil "$2" "$((angka / 10000)).$(((angka % 10000) / 100))"
  exit 0
fi

# Mode manual: setiap argumen adalah 1 versi.
if [ $# -gt 0 ]; then
  for v in "$@"; do hasil "versi diketik" "$v"; done
  exit 0
fi

ketemu=0
dilihat=" "
# Container Docker atau Podman dengan image pgadmin4. Paket podman-docker membuat docker memanggil podman, jadi lewati nama yang sama.
for rt in docker podman; do
  command -v "$rt" >/dev/null 2>&1 || continue
  while read -r nama image; do
    case "$image" in *pgadmin4*) ;; *) continue ;; esac
    case "$dilihat" in *" $nama "*) continue ;; esac
    dilihat="$dilihat$nama "
    v=$("$rt" exec "$nama" python3 -c 'import sys; sys.path.insert(0, "/pgadmin4"); import version; print(version.APP_VERSION)' 2>/dev/null)
    hasil "container $nama ($image)" "$v"; ketemu=1
  done < <("$rt" ps --format '{{.Names}} {{.Image}}' 2>/dev/null)
done

# Paket apt atau dnf dari repo resmi pgAdmin.
for p in pgadmin4-server pgadmin4-web pgadmin4-desktop; do
  v=""
  command -v dpkg-query >/dev/null 2>&1 && v=$(dpkg-query -W -f='${Version}' "$p" 2>/dev/null)
  [ -z "$v" ] && command -v rpm >/dev/null 2>&1 && v=$(rpm -q --qf '%{VERSION}' "$p" 2>/dev/null | grep -v 'not installed')
  [ -n "$v" ] && { hasil "paket $p" "${v%%[-~]*}"; ketemu=1; }
done

# Berkas version.py dari paket atau container.
for d in /usr/pgadmin4/web /pgadmin4; do
  [ -f "$d/version.py" ] || continue
  v=$(cd "$d" && python3 -c 'import version; print(version.APP_VERSION)' 2>/dev/null)
  hasil "berkas $d/version.py" "$v"; ketemu=1
done

[ "$ketemu" = 0 ] && echo "pgAdmin tidak ditemukan di mesin ini. Untuk pip: pip show pgadmin4. Untuk desktop: menu Help, About pgAdmin 4."
exit 0
# Di server: baca versi dari container, paket, atau berkas version.py
sudo bash cek-versi-pgadmin.sh
# Dari laptop: baca versi dari halaman login pgAdmin
bash cek-versi-pgadmin.sh --url https://ALAMAT-PGADMIN
# Cek versi yang Anda salin dari server lain
bash cek-versi-pgadmin.sh 9.14 9.18 9.19
Terminal: skrip cek versi membaca container pgadmin 9.18 sebagai RENTAN dan pgadmin-lab 9.19 sebagai AMAN. Mode manual dan mode halaman login memberi hasil sama.
Uji memakai podman. Perintah docker pada gambar memanggil podman, dan skrip membaca keduanya. Uji ini menemukan bug nama container ganda, lalu kami memperbaikinya. Sumber: uji Rama Digital di container podman dengan image resmi dpage/pgadmin4 9.18 dan 9.19, 2 November 2026.

Untuk pip, jalankan pip show pgadmin4 di virtualenv pgAdmin. Untuk desktop, buka menu Help, lalu About pgAdmin 4.

Cek hasil: "RENTAN" berarti lanjut ke langkah 2 dan 3 hari ini. "AMAN" tetap berarti jalankan langkah 5, karena celah ini ada di semua versi sebelum 29 Oktober.

Langkah 2: Cek siapa yang bisa memakai Import/Export Data

Celah ini butuh 1 akun dengan izin Import/Export Data, jadi daftar akun menentukan seberapa cepat Anda harus bergerak.

Simpan skrip ini sebagai cek-izin-pgadmin.py. Skrip hanya membaca database konfigurasi pgAdmin dalam mode read-only.

# Cek siapa yang bisa memakai alat Import/Export Data di pgAdmin 4 (CVE-2026-116241).
# Docker: docker exec -i pgadmin python3 - < cek-izin-pgadmin.py
# Paket:  sudo python3 cek-izin-pgadmin.py /var/lib/pgadmin/pgadmin4.db
# Skrip hanya membaca database konfigurasi pgAdmin. Skrip tidak mengubah apa pun.
import sqlite3
import sys

db = sys.argv[1] if len(sys.argv) > 1 else '/var/lib/pgadmin/pgadmin4.db'
c = sqlite3.connect(f'file:{db}?mode=ro', uri=True)
IZIN = 'tools_import_export_data'

roles = {rid: (name, perms) for rid, name, perms in c.execute('SELECT id, name, permissions FROM role')}
akun = list(c.execute(
    'SELECT u.email, u.auth_source, u.active, r.name, r.permissions FROM user u '
    'JOIN roles_users ru ON ru.user_id = u.id JOIN role r ON r.id = ru.role_id ORDER BY u.id'))
admin = [a for a in akun if a[3] == 'Administrator']
print(f'Database konfigurasi: {db}')
print(f'Akun pgAdmin: {len(akun)} (admin {len(admin)}, non-admin {len(akun) - len(admin)})')

for name, perms in roles.values():
    if name == 'Administrator':
        continue
    aktif = IZIN in (perms or '').split(',')
    status = 'AKTIF -> akun dengan role ini bisa memakai alat yang rentan' if aktif else 'dicabut -> OK'
    print(f'Role {name}: izin Import/Export Data {status}')

bisa = [a for a in akun if a[3] != 'Administrator' and IZIN in (a[4] or '').split(',')]
if bisa:
    print('Akun non-admin dengan izin itu:')
    for email, sumber, aktif, role, _ in bisa:
        print(f'  - {email} (role {role}, login {sumber}, {"aktif" if aktif else "nonaktif"})')

kolom = [r[1] for r in c.execute('PRAGMA table_info(server)')]
if 'passexec_cmd' in kolom:
    n = c.execute("SELECT COUNT(*) FROM server WHERE COALESCE(passexec_cmd, '') <> ''").fetchone()[0]
    catatan = ' -> isi SERVER_PASSEXEC_COMMANDS sebelum start pertama 9.19' if n else ''
    print(f'Server dengan Password Exec Command: {n}{catatan}')
# Docker atau Podman. Ganti pgadmin dengan nama container Anda.
docker exec -i pgadmin python3 - < cek-izin-pgadmin.py
# Paket apt atau dnf, mode web
sudo python3 cek-izin-pgadmin.py /var/lib/pgadmin/pgadmin4.db
Terminal: skrip izin pada pgAdmin 9.18 menampilkan 4 akun, role User dengan izin Import/Export Data AKTIF, dan 3 akun non-admin yang bisa memakai alat rentan.
Role User mendapat izin ini secara bawaan. Kami menambah 3 akun dummy dengan role User lewat perintah setup.py add-user. Sumber: uji Rama Digital di container podman dengan image resmi dpage/pgadmin4 9.18 dan 9.19, 2 November 2026.

Skrip ini membaca database SQLite bawaan. Bila pgAdmin Anda memakai PostgreSQL sebagai database konfigurasi, cek akun dan role lewat menu Users.

Cek hasil: "AKTIF" dan daftar akun non-admin berarti semua akun di daftar itu bisa memakai alat yang rentan. Bandingkan daftar itu dengan orang yang benar-benar butuh pgAdmin. Nonaktifkan akun yang tidak Anda kenal.

Langkah 3: Update ke pgAdmin 4 v9.19

Hanya update yang menutup 15 celah ini. Pilih perintah sesuai cara pasang dari langkah 1.

# Docker: tarik image baru, lalu buat ulang container dengan opsi lama Anda
docker pull dpage/pgadmin4:9.19
docker stop pgadmin && docker rm pgadmin
docker run -d --name pgadmin [opsi lama: -p, -e, -v] dpage/pgadmin4:9.19

# Docker Compose: ganti tag image di compose.yaml ke dpage/pgadmin4:9.19
docker compose pull pgadmin
docker compose up -d pgadmin

# Paket apt (Ubuntu, Debian) dari repo pgAdmin
sudo apt update
sudo apt install --only-upgrade pgadmin4 pgadmin4-web pgadmin4-server pgadmin4-desktop
sudo systemctl restart apache2

# Paket dnf (RHEL, Rocky, Fedora) dari repo pgAdmin
sudo dnf upgrade 'pgadmin4*'
sudo systemctl restart httpd

# Python wheel di virtualenv
pip install --upgrade pgadmin4==9.19

# Cek lagi sesudah update
sudo bash cek-versi-pgadmin.sh
Terminal: container 9.18 dihapus, image 9.19 ditarik, container dibuat ulang dengan volume yang sama. Skrip versi menulis AMAN dan 4 akun tetap ada.
Volume /var/lib/pgadmin menyimpan akun dan pengaturan. Container 9.19 memperbarui database konfigurasi saat start pertama. Sumber: uji Rama Digital di container podman dengan image resmi dpage/pgadmin4 9.18 dan 9.19, 2 November 2026.
  1. Backup volume /var/lib/pgadmin lebih dulu. Volume ini menyimpan akun, server terdaftar, dan pengaturan.
  2. Pakai opsi docker run yang sama dengan container lama: port, env, dan volume. Ganti hanya tag image.
  3. Jangan pakai tag latest tanpa cek versi. Tag yang Anda tarik sebelum 29 Oktober masih 9.18.
  4. Untuk paket apt, ikuti halaman download apt pgAdmin. Paket web memakai Apache, jadi restart Apache sesudah update.
  5. Jalankan lagi cek-versi-pgadmin.sh di setiap server.

Sebelum start pertama 9.19 di server mode

catatan rilis pgAdmin 4 v9.19 mengubah 4 perilaku di server mode. Cek item ini sebelum update, karena koneksi tertentu bisa berhenti.

  • Password Exec Command: perintah teks bebas diganti daftar SERVER_PASSEXEC_COMMANDS. Isi daftar itu sebelum start pertama. Bila kosong, perintah lama tidak dipakai dan log memberi peringatan.
  • Service libpq: server yang memakai service hanya jalan bila nama service ada di SERVER_MODE_ALLOWED_SERVICES.
  • Tunnel SSH: tunnel tidak lagi memakai kunci SSH akun layanan pgAdmin. Simpan berkas identitas di storage user.
  • Berkas password dan sertifikat klien: libpq tidak lagi memakai berkas milik akun layanan. Atur berkas itu di setiap server.

Langkah 2 menghitung server dengan Password Exec Command. Bila angkanya lebih dari 0, tambahkan daftar ini. Kami menguji baris env Docker ini di container 9.19, dan container start normal.

# Docker: tambahkan env ini ke container 9.19. Nilai memakai sintaks Python.
-e PGADMIN_CONFIG_SERVER_PASSEXEC_COMMANDS="{'vault': ['/usr/local/bin/ambil-password-pg', '--ttl', '300']}"

# Paket: tulis di /usr/pgadmin4/web/config_local.py
SERVER_PASSEXEC_COMMANDS = {
    'vault': ['/usr/local/bin/ambil-password-pg', '--ttl', '300'],
}
Tangga 6 baris: cek versi, cek izin Import/Export Data, update ke 9.19, 2 langkah berlabel tidak menutup celah (cabut izin, tutup akses), lalu cek tanda.
(1) sampai (3): urutan perbaikan. (4a) dan (4b): langkah sementara. Label merah mengingatkan bahwa hanya update yang menutup celah. Sumber: catatan rilis pgAdmin 4 v9.19, catatan CVE, dan analisa Rama Digital.

Cek hasil: skrip versi menulis "AMAN" di setiap server, dan skrip izin menampilkan jumlah akun yang sama dengan sebelum update.

Langkah 4: Batasi akses sampai update selesai

Langkah ini mengurangi siapa yang bisa memakai celah, tetapi tidak menutup celah.

Catatan CVE dan catatan rilis tidak menulis workaround resmi. Analisa Rama Digital: kami menyusun 2 langkah dari syarat celah. Kondisi: update belum bisa jalan hari ini. Batas: admin tetap punya izin penuh, dan akun admin yang bocor tetap berbahaya.

4a. Cabut izin Import/Export Data dari role non-admin

Menurut dokumentasi User Management, admin mengatur akun, role, dan izin di tab Users, Roles, dan Permissions. Login sebagai admin, buka menu akun di kanan atas, lalu pilih Users. Di tab Permissions, cari Import/Export Data, lalu cabut izin itu dari role User dan dari role buatan Anda.

Terminal: sesudah izin dicabut, skrip izin menulis role User: izin Import/Export Data dicabut, OK. Tidak ada akun non-admin yang bisa memakai alat itu.
Di uji, kami mencabut izin lewat database konfigurasi karena container uji tidak punya browser. Di server Anda, pakai menu Users di pgAdmin. Sumber: uji Rama Digital di container podman dengan image resmi dpage/pgadmin4 9.18 dan 9.19, 2 November 2026.

Jalankan lagi cek-izin-pgadmin.py. Kembalikan izin itu sesudah update ke 9.19 bila tim Anda butuh alat ekspor.

4b. Tutup pgAdmin dari internet

pgAdmin tidak perlu terbuka ke internet. Buka port hanya di 127.0.0.1, lalu akses lewat tunnel SSH atau VPN. Cara lain, izinkan hanya IP kantor di reverse proxy.

# Docker: buka port pgAdmin hanya di 127.0.0.1 server
docker run -d --name pgadmin -p 127.0.0.1:5050:80 [opsi lain] dpage/pgadmin4:9.19
# Dari laptop admin: buat tunnel SSH, lalu buka http://127.0.0.1:5050
ssh -L 5050:127.0.0.1:5050 admin@ALAMAT-SERVER

# Nginx di depan pgAdmin: izinkan hanya IP kantor atau VPN
location / {
    allow 198.51.100.10;
    deny all;
    proxy_pass http://127.0.0.1:5050;
}

IP contoh memakai blok dokumentasi RFC 5737. Kami tidak menjalankan contoh port ini di uji, karena aturan uji kami melarang port terbuka. Aktifkan juga two-factor authentication pgAdmin untuk akun admin.

Cek hasil: skrip izin menulis "dicabut", dan halaman login pgAdmin tidak terbuka dari jaringan lain, misalnya hotspot ponsel.

Langkah 5: Cari tanda pemakaian

Penyerang memakai akun pgAdmin yang sah, jadi bandingkan aktivitas dengan catatan tim.

Simpan skrip ini sebagai cek-tanda-pgadmin.py. Skrip menampilkan job Import/Export Data per akun, menandai job yang memuat kata PROGRAM, dan menampilkan akun dengan login gagal. Skrip tidak mencetak isi perintah job.

# Cek tanda pemakaian Import/Export Data dan tebakan password di pgAdmin 4.
# Docker: docker exec -i pgadmin python3 - < cek-tanda-pgadmin.py
# Paket:  sudo python3 cek-tanda-pgadmin.py /var/lib/pgadmin/pgadmin4.db
# Skrip hanya membaca riwayat proses dan data akun. Isi perintah tidak dicetak.
import sqlite3
import sys

db = sys.argv[1] if len(sys.argv) > 1 else '/var/lib/pgadmin/pgadmin4.db'
c = sqlite3.connect(f'file:{db}?mode=ro', uri=True)
admin = {u for (u,) in c.execute(
    "SELECT ru.user_id FROM roles_users ru JOIN role r ON r.id = ru.role_id WHERE r.name = 'Administrator'")}

jobs = [j for j in c.execute(
    'SELECT p.user_id, u.email, p.start_time, p.exit_code, p.command, p.arguments '
    'FROM process p LEFT JOIN user u ON u.id = p.user_id ORDER BY p.start_time')
    if (j[4] or '').endswith('psql') and 'copy' in (j[5] or '').lower()]
print(f'Job Import/Export Data di riwayat proses: {len(jobs)} (waktu UTC)')
for uid, email, mulai, kode, _, args in jobs:
    tanda = []
    if 'program' in (args or '').lower():
        tanda.append('TANDA: perintah memuat kata PROGRAM')
    if uid not in admin:
        tanda.append('akun non-admin')
    print(f'  {(mulai or "?")[:16]}  {email}  kode keluar {kode}  {", ".join(tanda) or "normal"}')

gagal = list(c.execute('SELECT email, login_attempts, locked FROM user WHERE login_attempts > 0 OR locked = 1'))
print(f'Akun dengan login gagal atau terkunci: {len(gagal)}')
for email, n, kunci in gagal:
    print(f'  - {email}: {n} kali gagal{", TERKUNCI" if kunci else ""}')
# Riwayat job Import/Export Data dan akun dengan login gagal
docker exec -i pgadmin python3 - < cek-tanda-pgadmin.py
# Request ke alat Import/Export dan ke view login lain di log akses container
docker logs pgadmin 2>&1 | grep -E '"POST /import_export/job/' | tail -n 20
docker logs pgadmin 2>&1 | grep -E '"POST /(login|verify|change|reset)' | tail -n 20
# Proses di container. Normal: python3, master, pickup, qmgr.
docker exec pgadmin ps -o user,pid,ppid,comm
Terminal: skrip tanda menampilkan 3 job Import/Export, 1 job berlabel TANDA kata PROGRAM dari akun non-admin, 1 admin TERKUNCI, log akses 0 request, dan daftar proses normal.
Semua job dan login gagal adalah data dummy yang kami tulis untuk menguji skrip. Skrip tidak mencetak isi perintah job. Sumber: uji Rama Digital di container podman dengan image resmi dpage/pgadmin4 9.18 dan 9.19, 2 November 2026.
Dua kolom tanda: di pgAdmin (job Import/Export tidak biasa, kata PROGRAM, akun terkunci, akun baru) dan di host (proses shell, POST ke view login lain, koneksi keluar).
Kolom amber: tanda di dalam pgAdmin. Kolom merah: tanda di host dan jaringan. Kotak bawah: langkah bila Anda menemukan 1 tanda saja. Sumber: catatan CVE, uji podman Rama Digital, dan analisa Rama Digital.

Image Docker resmi menulis log akses ke stdout, jadi docker logs memuat setiap request. Form login pgAdmin mengirim data ke /authenticate/login. Analisa Rama Digital: POST ke /login, /verify, /change, atau /reset bukan alur form biasa, jadi periksa sumber IP-nya.

Cek hasil: semua job berasal dari akun yang Anda kenal, tidak ada label "TANDA", dan proses di container hanya proses normal. Riwayat job bisa dihapus dari UI, jadi tidak ada tanda belum berarti aman.

Bila ada 1 tanda saja, putus pgAdmin dari jaringan, lalu simpan log dan pgadmin4.db sebagai bukti. Ganti password semua akun pgAdmin dan password database yang tersimpan di pgAdmin. Ganti kunci SSH dan rahasia di host, lalu bangun ulang container dari image 9.19.

Bila database berisi data pelanggan, UU 27/2022 tentang Pelindungan Data Pribadi mewajibkan pemberitahuan tertulis paling lambat 3 kali 24 jam sesudah kebocoran data pribadi. Baca juga panduan security, privacy, dan UU PDP untuk perusahaan.

Contoh: 1 pagi respons untuk 3 pgAdmin

Simulasi ini memakai data dummy. Nama server, waktu, dan hasil bukan data pelanggan.

Waktu (WIB)Server dummyYang dicekHasilTindakan
08.00pga-tim (Docker 9.18, terbuka ke internet)Langkah 1 dan 2RENTAN, 6 akun non-adminLangkah 4a dan 4b, lalu update
08.30pga-lab (Docker latest, ditarik Agustus)Langkah 1RENTAN, tag latest lamaTarik ulang 9.19
09.00laptop-dba (desktop 9.14)Langkah 1RENTAN, 1 penggunaPasang installer 9.19
09.30pga-timLangkah 51 job dari akun vendor pada 02.14Respons insiden, ganti password database

Pelajaran dari simulasi: versi aman tidak membuktikan server bersih. Pga-tim sudah update, tetapi langkah 5 tetap menemukan job dari sebelum update.

Siapa yang memasang patch

Tanggung jawab patch berbeda per cara pasang, jadi tabel ini membantu Anda tahu siapa yang bergerak hari ini.

Cara pasangPemegang patchYang Anda kerjakan
Container Docker di server sendiriTim Anda menarik image 9.19Langkah 1 sampai 5
Paket apt atau dnf dari repo pgAdminTim Anda menjalankan update paketLangkah 1 sampai 5
pgAdmin dari panel hosting atau image VPS siap pakaiPenyedia hosting atau tim AndaMinta bukti versi tertulis, lalu langkah 2 dan 5
Desktop di laptop adminPemilik laptopPasang installer 9.19

Rekomendasi Rama Digital: perlakukan pgAdmin seperti kunci utama database. Batasi akun dengan prinsip hak akses minimum, seperti di panduan hak akses, approval, dan audit log. Update juga runtime di server yang sama, misalnya untuk peringatan PHP2Shell. Untuk standar pemeriksaan yang lebih luas, baca standar audit keamanan dan pentest.

Checklist hari ini

  1. Buat daftar semua pgAdmin: server, container, dan laptop. Pemilik: tim infrastruktur. Bukti: daftar nama dan versi.
  2. Cek versi dengan langkah 1. Pemilik: admin server. Bukti: output skrip.
  3. Cek akun dan izin dengan langkah 2. Pemilik: admin pgAdmin. Bukti: output skrip.
  4. Pasang langkah 4 di setiap pgAdmin yang belum bisa update hari ini. Pemilik: admin pgAdmin. Bukti: skrip izin menulis "dicabut".
  5. Update ke 9.19. Isi SERVER_PASSEXEC_COMMANDS dulu bila perlu. Pemilik: admin server. Bukti: output skrip sesudah update.
  6. Periksa tanda dengan langkah 5. Pemilik: admin server dan tim keamanan. Bukti: output skrip dan log akses.
  7. Hapus akun yang tidak dipakai, dan aktifkan two-factor authentication untuk admin.

Tanya jawab

Saya memakai pgAdmin desktop di laptop. Apakah saya aman?

Risiko Anda rendah, karena desktop mode hanya punya 1 pengguna lokal. Tetap pasang installer 9.19, karena rilis ini menutup 15 celah.

Apakah penyerang tanpa akun bisa memakai CVE-2026-116241?

Tidak langsung. Celah ini butuh 1 akun pgAdmin dengan izin Import/Export Data. Tetapi CVE-2026-116238 membuat tebakan password tanpa batas, jadi pgAdmin yang terbuka ke internet tetap berisiko tinggi.

Apakah celah ini sudah dipakai menyerang?

Per 2 November 2026, kami tidak menemukan laporan serangan, dan celah ini belum masuk CISA KEV. Halaman login menampilkan nomor versi, jadi server rentan mudah ditemukan.

Saya sudah update ke 9.18 pada September. Kenapa masih rentan?

Versi 9.18 memperbaiki CVE-2026-17566. CVE-2026-116241 adalah bypass dari perbaikan itu, jadi semua versi di bawah 9.19 rentan.

Apakah mencabut izin Import/Export Data bisa menggantikan update?

Tidak. Langkah itu hanya menutup 1 dari 15 celah, dan akun admin tetap punya izin. Update ke 9.19 tetap wajib.

Apakah akun dan server terdaftar hilang saat container dibuat ulang?

Tidak, bila Anda memakai volume yang sama untuk /var/lib/pgadmin. Uji kami membuat ulang container 9.18 ke 9.19, dan 4 akun tetap ada. Backup volume itu lebih dulu.

Saya memakai pgAdmin dari penyedia hosting. Apa yang saya kerjakan?

Minta bukti versi tertulis dari penyedia. Lalu cek versi dari halaman login dengan langkah 1, dan periksa akun Anda di menu Users.

Langkah berikutnya

Batas yang tetap berlaku: langkah 4 tidak menutup celah, dan update tidak menghapus akses yang sudah dipakai penyerang. Bila pgAdmin Anda menunjukkan tanda di langkah 5, atau Anda butuh bantuan audit dan pemulihan, pakai Vibe Code Rescue. Untuk 1 kendala yang mendesak hari ini, jadwalkan sesi 30 menit.

Sumber