Your RSA-2048 keys break in 2030. Find every one of them before attackers do.
🐹
🐹 Go
Not in CISA KEV
HIGH severity

CVE-2026-107810 — Nginx-UI

HIGHFix: 0xJacky/nginx-ui@a467ed6

CVE-2026-107810 is a high-severity (CVSS 8.1) CWE-59 vulnerability in github.com/0xJacky/Nginx-UI. A fix is available for github.com/0xJacky/Nginx-UI — see the affected versions and patch details below.

Nginx UI: Backup restore follows crafted symlinks into the live Nginx configuration path before restore flags are applied

Also known asGHSA-p8v3-89rh-jxc7
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
None indexed
Exploitation data as of Oct 10, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

EPSS Exploitation Probability

via FIRST.org ↗
0.4%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs28th percentile — riskier than 28% of all scored CVEsHighest risk

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

CVE-2026-107810 by exploitation likelihood (EPSS) against impact (CVSS). Outside the shaded patch-first corner.

Where this sits among everything scored

Of 394,415 CVEs with a current EPSS score, this one falls in the < 10% band (highlighted). Counts from FIRST.org, log-scaled.

Real-World Exposure

1 pkg affected
🐹github.com/0xJacky/Nginx-UI

Real-time download stats are indexed for npm and PyPI packages. This vulnerability affects Go packages — download data is not available via public APIs for these ecosystems.

Description

Summary

An authenticated user who can create and restore a backup can craft a valid backup archive that causes the restore staging process to write attacker-controlled files into the live Nginx configuration path even when both restore_nginx and restore_nginx_ui are set to false.

Details

The restore flow always extracts the outer archive, verifies the manifest, decrypts nginx-ui.zip and nginx.zip, and extracts both inner archives before it decides whether RestoreNginx or RestoreNginxUI should be applied. The zip extractor explicitly allows absolute symlinks when the link target is under nginx.GetConfPath() or nginx.GetModulesPath(). Later regular-file entries are then created with os.OpenFile() on the symlinked path, which follows the symlink and writes into the live path.

Relevant code paths:

This means the restore trust boundary is broken during extraction. A restore request that explicitly opted out of restoring either Nginx or Nginx UI can still modify the live Nginx configuration tree during staging.

PoC

I verified this locally in an isolated environment with a temporary package-level harness that exercised the real Backup() and Restore() implementations.

What the executed test did:

  1. Created a temporary app.ini, database file, and a temporary live Nginx config directory.
  2. Called the real Backup() implementation to obtain a valid backup archive plus AES key/IV.
  3. Extracted the outer backup, decrypted nginx.zip, replaced it with a crafted zip containing:
    • a symlink entry link -> <live nginx conf dir>
    • a later regular file entry link/poc.conf
  4. Recomputed manifest.json size/hash values for the modified encrypted nginx.zip and re-signed manifest.sig with the expected signing key derived from the AES key.
  5. Repacked the outer archive and called the real Restore() implementation with:
    • RestoreNginx: false
    • RestoreNginxUI: false
  6. Verified that <live nginx conf dir>/poc.conf was created anyway.

Observed result from the actual local verification:

  • The crafted restore completed successfully with both restore flags set to false.
  • The asserted sink was the existence and content of the live-path file written during restore staging.

Impact

Any deployment that allows an authenticated user to create and restore backups is affected. A crafted restore archive can modify the live Nginx configuration path before either restore toggle is honored. This can lead to persistent configuration injection, denial of service on a later reload, or other follow-on impact depending on what files the deployment later consumes from the modified path.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
🐹Gogithub.com/0xJacky/Nginx-UI≥ 1.9.10-0.20250517140552-daee3ac7ade1&&< 1.9.10-0.20260728074146-a467ed6525911.9.10-0.20260728074146-a467ed652591go get github.com/0xJacky/Nginx-UI@v1.9.10-0.20260728074146-a467ed652591

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for github.com/0xJacky/Nginx-UI, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update github.com/0xJacky/Nginx-UI to 1.9.10-0.20260728074146-a467ed652591 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-107810 is resolved across your whole dependency graph.

  3. Workarounds

    Cap what an attacker can consume: apply request size, rate and timeout limits in front of the affected component, and run it with memory and CPU limits so exhaustion degrades one worker rather than the whole service.

Frequently Asked Questions

### Summary An authenticated user who can create and restore a backup can craft a valid backup archive that causes the restore staging process to write attacker-controlled files into the live Nginx configuration path even when both `restore_nginx` and `restore_nginx_ui` are set to `false`. ### Details The restore flow always extracts the outer archive, verifies the manifest, decrypts `nginx-ui.zip` and `nginx.zip`, and extracts both inner archives before it decides whether `RestoreNginx` or `RestoreNginxUI` should be applied. The zip extractor explicitly allows absolute symlinks when the link
O3 Security · Impact-Aware SCA

Is CVE-2026-107810 in your dependencies?

Find it across Go, including transitive dependencies.

CVE-2026-107810: Nginx-UI DoS — Fix Available