Servers, proxies and network services
Apache CouchDB: CVE-2026-86471 admin to operating system commands
CouchDB check
An unvalidated runtime configuration value in Apache CouchDB lets a CouchDB server admin run arbitrary shell commands as the operating system user that runs CouchDB. It needs admin credentials, so it is a privilege escalation from a CouchDB admin to the host: a stolen or weak admin password, an exposed admin interface, or a compromised application that holds admin credentials. It is not something an anonymous visitor can use alone.
| CVE | CVE-2026-86471 (published 20 October 2026) |
| Severity | Critical: 9.3 on the CVSS 4.0 scale (privileges required: high) |
| Affected | Apache CouchDB 3.5.2 and earlier, on all platforms |
| Fixed | 3.5.3 |
| Needs | Server-admin credentials |
| Exploited | No exploitation has been reported |
| Same release | 3.5.3 also fixes other CouchDB flaws, including a pre-authentication gzip decompression bomb on POST /_session. That one needs no credentials, which is why the bind address matters |
Quick start
-
Download the script. The repository is mirrored on GitHub and Codeberg; pick a base URL.
# BASE from GitHub: https://raw.githubusercontent.com/PrivacySafe/security-patches/refs/heads/main # BASE from Codeberg: https://codeberg.org/PrivacySafe/security-patches/raw/branch/main # curl -fLO "$BASE/couchdb/couchdb-check.sh" curl -fLO https://raw.githubusercontent.com/PrivacySafe/security-patches/refs/heads/main/couchdb/couchdb-check.sh -
Read it before running it, then make it executable.
less couchdb-check.sh chmod +x couchdb-check.sh -
Check this host. With no arguments it reads the release files, the installed package and asks only
http://127.0.0.1:5984/. To check other servers, pass their URLs../couchdb-check.sh check ./couchdb-check.sh check http://10.0.0.5:5984/ http://10.0.0.6:5984/
Commands
| Command | What it does |
|---|---|
check [URL ...] (default) |
Reads the version from releases/start_erl.data under /opt/couchdb, from the dpkg or rpm package, and from a single unauthenticated GET / of each URL (the root document, which reports the version). Reads the ini files for bind_address, require_valid_user and the number of [admins] entries |
version |
Prints the script version |
Environment: COUCHDB_ROOT (default /opt/couchdb) and COUCHDB_ETC (space separated, default /opt/couchdb/etc /etc/couchdb /usr/local/etc/couchdb) point the script at unusual layouts.
Exit codes: 0 nothing affected, 1 an affected version was found, 2 bad arguments.
Credentials are never printed
The [admins] section holds password hashes or passwords. The script counts the entries and never prints a value from that section.
How to read the result
- Affected version: upgrade to 3.5.3. The script exits
1for any affected version, because it cannot judge how well your admin credentials are protected. bind_addressis0.0.0.0or::: CouchDB listens on every interface. The unauthenticated/_sessionflaw fixed in the same release is then reachable by anyone who can connect. The script reads the last value acrossdefault.ini,default.d,local.iniandlocal.d, and ignores commented lines.bind_addressis loopback: reported as a good sign, not as a fix.- Several sources: the release files, the package and each live URL are reported separately. A running server that answers with a different version from the files on disk usually means it was upgraded but not restarted, or the reverse.
- Distribution packages: the script reads the package changelog for a mention of the CVE.
- A server that requires a login for
GET /simply gives no version. The script says it got no answer.
Fixing it
Upgrade to CouchDB 3.5.3 or later and restart. Until you can, keep port 5984 off untrusted networks, give admins long unique passwords, and do not let applications hold admin credentials they do not need. Those steps are PrivacySafe's recommendation. After upgrading, rotate any admin password that may have been exposed.
Sources
Before you run it
- The fix. Update to 3.5.3. The same release fixes a pre-authentication gzip decompression bomb on
POST /_session, which needs no credentials, so whether the node listens beyond localhost matters. - CVE-2026-86471 needs a server admin. It is a privilege escalation from a CouchDB admin (a stolen or weak password, an exposed admin interface, or an application holding admin credentials) to the host. It is not usable by an anonymous visitor alone.
- Given URLs, it asks each server for its version. With a URL argument it makes one unauthenticated
GETof the server's root document. With none it asks onlyhttp://127.0.0.1:5984/and ignores a refusal. - It never prints an
[admins]value. Those are password hashes or passwords. It reports only the bind address,require_valid_userand how many admin entries exist. - It also checks running docker and podman containers, unless you name a directory or set
SCAN_CONTAINERS=0. A read-only probe inside each running docker and podman container capturesreleases/start_erl.dataand the.inifiles (with every value under[admins]redacted inside the container before it is copied) into a private temporary directory. The script then runs once per container, in isolation, against that copy, so one container's configuration never changes another's result. A container run reads only those copied files: it does not ask the host package database or a live server. The copies are removed on exit. A path shown as.../docker_NAME/...is inside the container NAME. It is skipped when you name a binary or directory yourself.
The Security Patches software and this documentation are dedicated to the public domain under CC0 1.0 Universal. Other pages on privacysafe.app/docs are CC BY-SA 4.0 unless the page says otherwise.