NginxProxyManager / NginxProxyManager/nginx-proxy-manager
RCE via Shell Injection in DNS Credentials (Nginx Proxy Manager) - CVE-2026-40519
Nobody has claimed this yet.
- Dominant language
- TypeScript
- Stars
- 34.2k
- Forks
- 3.9k
- Avg merge
- 21h 12m
- Merged PRs (30d)
- 20
Description
Summary
Nginx Proxy Manager is vulnerable to authenticated remote code execution due to a shell injection in setupCertbotPlugins() (backend/setup.js).
The user-controlled field dns_provider_credentials is interpolated into a shell command executed via child_process.exec() without proper escaping.
An attacker with certificates:manage permission can inject arbitrary commands, executed on backend restart (typically as root in Docker deployments).
Affected Versions
v2.9.14 v2.9.15 v2.9.16 v2.9.17 v2.9.18 v2.9.19 v2.9.20
v2.9.21 v2.9.22
v2.10.0 v2.10.1 v2.10.2 v2.10.3 v2.10.4
v2.11.0 v2.11.1 v2.11.2 v2.11.3
v2.12.0 v2.12.1 v2.12.2 v2.12.3 v2.12.4 v2.12.5 v2.12.6
v2.13.0 v2.13.1 v2.13.2 v2.13.3 v2.13.4 v2.13.5 v2.13.6 v2.13.7
v2.14.0 (latest, still vulnerable)
Root Cause
Incorrect escaping order:
const escapedCredentials = certificate.meta.dns_provider_credentials
.replaceAll("'", "\\'")
.replaceAll("\\", "\\\\");
Backslashes are escaped after single quotes, breaking the protection and allowing injection.
Example input:
x' ; cmd ; #
Results in command execution:
echo 'x\\' ; cmd ; #'
Exploitation
- Store payload in
dns_provider_credentials(DB or race condition) - Restart backend
- Payload executes via
/bin/sh -cinsideexec()
Reliable in Docker since /etc/letsencrypt/credentials/ is not persisted.
Example payload:
fake' > /dev/null; CMD ; echo '
Impact
- Full RCE
- Access to secrets, TLS keys, database
- Service disruption and persistence
Fix
.replaceAll("\\", "\\\\")
.replaceAll("'", "\\'");
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in backend/setup.js at setupCertbotPlugins() and trace how dns_provider_credentials reaches child_process.exec(). Verify the escaping behavior with the payload pattern described in the issue, then add regression coverage showing that credentials cannot alter the shell command while normal DNS credentials still work.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- docker, javascript
- Domain
- backend, security
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100