{"id":"GO-2026-6703","revision":null,"records":[{"revision":"3c3cc4e5e2c848fdb2c4c9a5b200069a","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-107809","aliases":[],"title":"Nginx-UI AuthRequired token cookie fallback enables CSRF against management APIs","description":"Nginx UI is a web user interface for the Nginx web server. From 2.0.0 until 2.5.0, AuthRequired accepts a browser-managed token cookie as an API credential after the front end stores the JWT in that cookie. Because management endpoints do not universally require a CSRF token or perform Origin or Referer validation, a remote attacker can induce a logged-in administrator's browser to submit authenticated cross-site state-changing requests, including POST /api/configs. The attack requires an administrator account without OTP/Passkey or a target endpoint that does not require secure-session proof. The attacker cannot read the cross-origin response but can modify Nginx configuration, trigger reloads, or invoke other management operations reachable with the victim's session. This issue is fixed in version 2.5.0.","state":0,"publishedAt":"2026-10-09T15:22:10.562+00:00","modifiedAt":"2026-10-09T16:45:22.243+00:00","affected":[{"ecosystem":"Vendor product","name":"nginx-ui","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"0xJacky\",\n                    \"product\": \"nginx-ui\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 2.0.0, < 2.5.0\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","score":8.8,"severity":"HIGH"}],"references":["https://github.com/0xJacky/nginx-ui/security/advisories/GHSA-33rr-wq23-g6gg","https://github.com/0xJacky/nginx-ui/commit/a3999bd78a3b97ab22e6b5e9fd478ac57598a954","https://github.com/0xJacky/nginx-ui/releases/tag/v2.5.0"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-107809","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-107809","identifiers":["CVE-2026-107809"]},"retained":false,"historicalAffected":[]},{"revision":"25853ee3e1d049fdb84e1985a1955e61","observedAt":"2026-11-07T04:31:37.249+00:00","statement":{"source":"euvd","id":"EUVD-2026-95892","aliases":["CVE-2026-107809","GHSA-33rr-wq23-g6gg"],"title":"Nginx UI is a web user interface for the Nginx web server. From 2.0.0 until 2.5.0, AuthRequired accepts a browser-managed token cookie as an API credential after the front end stores the JWT in that cookie. Because management endpoints do n…","description":"Nginx UI is a web user interface for the Nginx web server. From 2.0.0 until 2.5.0, AuthRequired accepts a browser-managed token cookie as an API credential after the front end stores the JWT in that cookie. Because management endpoints do not universally require a CSRF token or perform Origin or Referer validation, a remote attacker can induce a logged-in administrator's browser to submit authenticated cross-site state-changing requests, including POST /api/configs. The attack requires an administrator account without OTP/Passkey or a target endpoint that does not require secure-session proof. The attacker cannot read the cross-origin response but can modify Nginx configuration, trigger reloads, or invoke other management operations reachable with the victim's session. This issue is fixed in version 2.5.0.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","score":8.8,"severity":null}],"references":["https://github.com/0xJacky/nginx-ui/security/advisories/GHSA-33rr-wq23-g6gg","https://github.com/0xJacky/nginx-ui/commit/a3999bd78a3b97ab22e6b5e9fd478ac57598a954","https://github.com/0xJacky/nginx-ui/releases/tag/v2.5.0"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-95892","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Oct 9, 2026, 3:22:10 PM","dateUpdated":"Oct 9, 2026, 4:45:22 PM"},"relatedAdvisories":[],"note":"EUVD source date text has no stated timezone and is retained without inventing a UTC instant. Related bulletin membership is not an alias, common cause or applicability claim. A missing vector with a zero score is treated as unrated. Complete vendor/product and underlying source evidence remains in the original JSON."},"key":"euvd:EUVD-2026-95892","identifiers":["EUVD-2026-95892","CVE-2026-107809","GHSA-33rr-wq23-g6gg"]},"retained":false,"historicalAffected":[]},{"revision":"a833d779b76346b39b4c2b97fcfd089e","observedAt":"2026-10-25T05:17:13.11+00:00","statement":{"source":"nvd","id":"CVE-2026-107809","aliases":[],"title":"Nginx UI is a web user interface for the Nginx web server. From 2.0.0 until 2.5.0, AuthRequired accepts a browser-managed token cookie as an API credential after the front end stores the JWT in that cookie. Because management endpoints do n…","description":"Nginx UI is a web user interface for the Nginx web server. From 2.0.0 until 2.5.0, AuthRequired accepts a browser-managed token cookie as an API credential after the front end stores the JWT in that cookie. Because management endpoints do not universally require a CSRF token or perform Origin or Referer validation, a remote attacker can induce a logged-in administrator's browser to submit authenticated cross-site state-changing requests, including POST /api/configs. The attack requires an administrator account without OTP/Passkey or a target endpoint that does not require secure-session proof. The attacker cannot read the cross-origin response but can modify Nginx configuration, trigger reloads, or invoke other management operations reachable with the victim's session. This issue is fixed in version 2.5.0.","state":0,"publishedAt":"2026-10-09T16:17:25.387+00:00","modifiedAt":"2026-10-20T15:15:58.807+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","score":8.8,"severity":"HIGH"}],"references":["https://github.com/0xJacky/nginx-ui/commit/a3999bd78a3b97ab22e6b5e9fd478ac57598a954","https://github.com/0xJacky/nginx-ui/releases/tag/v2.5.0","https://github.com/0xJacky/nginx-ui/security/advisories/GHSA-33rr-wq23-g6gg"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-107809","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Analyzed","weaknesses":["CWE-352"],"productCriteria":["cpe:2.3:a:nginxui:nginx_ui:*:*:*:*:*:*:*:*"],"sourceDates":{"published":"2026-10-09T16:17:25.387","lastModified":"2026-10-20T15:15:58.807"},"relatedAdvisories":[],"note":"NVD analysis and CPE criteria are source context, not proof that a package or your environment is affected. Complete affected data, logical configurations and SSVC are retained in the original JSON."},"key":"nvd:CVE-2026-107809","identifiers":["CVE-2026-107809"]},"retained":false,"historicalAffected":[]},{"revision":"6cb7d8d24ebb4d06abef7b0a65d72dfe","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-33rr-wq23-g6gg","aliases":["CVE-2026-107809","GO-2026-6703"],"title":"Nginx-UI AuthRequired token cookie fallback enables CSRF against management APIs","description":"## Summary\nNginx-UI v2.4.3 stores the API JWT in a browser cookie named `token` and the `AuthRequired` middleware accepts that cookie as an authentication source. Because management endpoints are protected by `AuthRequired` and do not enforce a universal CSRF token or Origin/Referer check, a remote attacker can induce a logged-in administrator to submit cross-site state-changing requests. The attacker does not need to read the cross-origin response; the browser-sent cookie is enough to authenticate the request.\n\n## Details\nThe root cause is a trust-boundary failure between browser-managed cookies and API bearer-token authentication. In `app/src/pinia/moudule/user.ts:25-35`, the front end writes the JWT to a `token` cookie when the token changes. In `internal/middleware/middleware.go:16-36`, `getToken` first checks the `Authorization` header and `token` query parameter, then falls back to `c.Cookie(\"token\")`. That fallback causes browser-initiated cross-site requests to carry a valid API credential automatically. The route group in `router/routers.go:87-110` applies `middleware.AuthRequired()` to many management modules, including `config.InitRouter`, `nginx.InitRouter`, `settings.InitRouter`, and backup-related handlers. For accounts without OTP/Passkey, `RequireSecureSession` does not provide a universal second factor for all state-changing operations. A representative sink is `api/config/add.go:68-78`, where an authenticated request writes Nginx configuration with `os.WriteFile` and then calls `nginx.Control(nginx.Reload)`. CORS does not mitigate this issue because preventing cross-origin response reads does not prevent cross-site form or no-cors requests from being sent with cookies.\n\nCore vulnerable code path:\n\n```typescript\n// app/src/pinia/moudule/user.ts:25-35\nwatch(token, v => {\n    if (v) {\n      cookies.set('token', v, getCookieOptions(86400))\n      if (!shortToken.value) {\n        void fetchShortToken()\n      }\n    }\n    else {\n      cookies.remove('token', { path: '/' })\n      shortToken.value = ''\n    }\n  })\n```\n\nThe front end stores the authentication token in a `token` cookie. The cookie is created client-side and is not shown here as HttpOnly; it becomes the credential that the back end later accepts through cookie fallback.\n\n```go\n// internal/middleware/middleware.go:16-36\n// getToken from header, cookie or query\nfunc getToken(c *gin.Context) (token string) {\n\tif token = c.GetHeader(\"Authorization\"); token != \"\" {\n\t\treturn\n\t}\n\n\tif token = c.Query(\"token\"); token != \"\" {\n\t\tif len(token) > 16 {\n\t\t\t// Long token (base64 encoded JWT)\n\t\t\ttokenBytes, _ := base64.StdEncoding.DecodeString(token)\n\t\t\treturn string(tokenBytes)\n\t\t}\n\t\t// Short token (16 characters)\n\t\treturn token\n\t}\n\n\tif token, _ = c.Cookie(\"token\"); token != \"\" {\n\t\treturn token\n\t}\n\n\treturn \"\"\n}\n```\n\n`getToken` accepts the `token` cookie as an authentication credential after checking the header and query parameter. That behavior lets a browser-sent cookie authenticate state-changing API requests triggered from another origin.\n\n```go\n// router/routers.go:87-110\n// Authorization required and not websocket request\n\t\tg := root.Group(\"/\", middleware.AuthRequired(), middleware.Proxy())\n\t\t{\n\t\t\tdebug.InitRouter(g)\n\t\t\tuser.InitUserRouter(g)\n\t\t\tanalytic.InitRouter(g)\n\t\t\tuser.InitManageUserRouter(g)\n\t\t\tnginx.InitRouter(g)\n\t\t\tsites.InitRouter(g)\n\t\t\tstreams.InitRouter(g)\n\t\t\tconfig.InitRouter(g)\n\t\t\ttemplate.InitRouter(g)\n\t\t\tcertificate.InitCertificateRouter(g)\n\t\t\tcertificate.InitDNSCredentialRouter(g)\n\t\t\tcertificate.InitAcmeUserRouter(g)\n\t\t\tdnsapi.InitRouter(g)\n\t\t\tsystem.InitPrivateRouter(g)\n\t\t\tsettings.InitRouter(g)\n\t\t\tllm.InitRouter(g)\n\t\t\tcluster.InitRouter(g)\n\t\t\tnotification.InitRouter(g)\n\t\t\texternal_notify.InitRouter(g)\n\t\t\tbackup.InitAutoBackupRouter(g)\n\t\t\tnginxLog.InitRouter(g)\n\t\t\tupstream.InitHTTPRouter(g)\n```\n\nMany management modules, including Nginx, configuration, settings, backup, and user management, are placed behind `AuthRequired`. The cookie fallback therefore protects high-impact state-changing routes, not only read-only endpoints.\n\n```go\n// api/config/add.go:68-78\nerr = os.WriteFile(path, []byte(content), 0644)\n\tif err != nil {\n\t\tcosy.ErrHandler(c, err)\n\t\treturn\n\t}\n\n\tres := nginx.Control(nginx.Reload)\n\tif res.IsError() {\n\t\tres.RespError(c)\n\t\treturn\n\t}\n```\n\nThis representative sink shows why the CSRF is high impact: once authenticated through the cookie fallback, a request can write Nginx configuration content and trigger a reload.\n\n## POC\nPrerequisites: an administrator is logged in to Nginx-UI and has a browser `token` cookie; the administrator account has not enabled OTP/Passkey, or the chosen target endpoint does not require secure-session proof; the attacker knows the Nginx-UI management URL and can induce the administrator to visit an attacker-controlled page. Reproduction: (1) Host an attacker page at `GET /csrf.html` that automatically submits a cross-site request to the victim instance. (2) The page submits `POST /api/configs` with configuration fields such as `base_dir`, `name`, `content`, `overwrite`, and `sync_node_ids`; the attacker does not need to read the response. (3) When the administrator visits the page, the browser attaches the victim site's `token` cookie. (4) Expected result: `AuthRequired` authenticates from the cookie, `AddConfig` writes the Nginx configuration, and the application attempts an Nginx reload. Testing should use a harmless configuration in an isolated environment.\n\n## Impact\nAn attacker can trigger administrative operations while an administrator is logged in, including Nginx configuration creation or modification, reload/restart operations, settings changes, and backup-related actions depending on endpoint protections. Direct impacts include traffic redirection, reverse proxy tampering, denial of service, and sensitive configuration changes. In deployments with permissive Nginx modules or dangerous configuration capabilities, configuration tampering may lead to further server-side impact or internal network abuse.","state":0,"publishedAt":"2026-10-09T17:08:10+00:00","modifiedAt":"2026-10-19T21:41:07.2843279+00:00","affected":[{"ecosystem":"Go","name":"github.com/0xJacky/Nginx-UI","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"1.9.10-0.20250517140552-daee3ac7ade1"},{"kind":"fixed","version":"1.9.10-0.20260728074433-a3999bd78a3b"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:U/C:H/I:H/A:H","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/0xJacky/nginx-ui/security/advisories/GHSA-33rr-wq23-g6gg","https://github.com/0xJacky/nginx-ui/commit/a3999bd78a3b97ab22e6b5e9fd478ac57598a954","https://github.com/0xJacky/nginx-ui","https://github.com/0xJacky/nginx-ui/releases/tag/v2.5.0"],"sourceUrl":"https://github.com/advisories/GHSA-33rr-wq23-g6gg","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-33rr-wq23-g6gg","identifiers":["GHSA-33rr-wq23-g6gg","CVE-2026-107809","GO-2026-6703"]},"retained":false,"historicalAffected":[]},{"revision":"874c03354c944333bf3ac3cf4196db3a","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-6703","aliases":["CVE-2026-107809","GHSA-33rr-wq23-g6gg"],"title":"Nginx-UI AuthRequired token cookie fallback enables CSRF against management APIs in github.com/0xJacky/Nginx-UI","description":"Nginx-UI AuthRequired token cookie fallback enables CSRF against management APIs in github.com/0xJacky/Nginx-UI","state":0,"publishedAt":"2026-10-19T21:08:26+00:00","modifiedAt":"2026-10-19T21:31:52.2742846+00:00","affected":[{"ecosystem":"Go","name":"github.com/0xJacky/Nginx-UI","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"1.9.10-0.20250517140552-daee3ac7ade1"},{"kind":"fixed","version":"1.9.10-0.20260728074433-a3999bd78a3b"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/0xJacky/nginx-ui/security/advisories/GHSA-33rr-wq23-g6gg","https://github.com/0xJacky/nginx-ui/commit/a3999bd78a3b97ab22e6b5e9fd478ac57598a954","https://github.com/0xJacky/nginx-ui/releases/tag/v2.5.0"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-6703","license":"OSV · upstream source license applies","key":"osv:GO-2026-6703","identifiers":["GO-2026-6703","CVE-2026-107809","GHSA-33rr-wq23-g6gg"]},"retained":false,"historicalAffected":[]}],"coverage":[{"source":"cisa-kev:global","scope":"Complete CISA KEV catalog; all vendors. Missing entries do not establish absence of exploitation.","generation":"2026-11-08T13:04:23.5160344+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-08T13:04:23.5160344+00:00","lastSuccessAt":"2026-11-08T13:04:23.701507+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:23.7015079+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-eaa64dac63caa79c8d4905619258c41c51b39e461b996124e1a21b5e85e7e738-5e9a1b25b88c72db8d3c46be95e52009e07ae4af884484ac8e34e4d7f79f07eb","complete":true,"records":421098,"lastAttemptAt":"2026-11-08T13:04:23.0585244+00:00","lastSuccessAt":"2026-11-08T13:04:23.0353669+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:23.0585244+00:00","snapshotPublishedAt":"2026-11-08T12:20:14+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"euvd","scope":"Rolling EUVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global EUVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-383c643166b94ac4b6a615647191978e","complete":true,"records":13654,"lastAttemptAt":"2026-11-08T13:04:50.0771652+00:00","lastSuccessAt":"2026-11-08T13:04:50.073+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:50.073+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13706,"expectedIdentifiers":13706,"failedIdentifiers":0},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-11-08T13:04:23.5160344+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-08T13:04:23.5160344+00:00","lastSuccessAt":"2026-11-08T13:04:23.7022986+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:23.7022987+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"nvd","scope":"Rolling NVD lookups of CVE aliases in current public OSV archives; 500 identifiers per refresh, rechecked after 48 hours. Not a global NVD catalog. Successful not-found lookups count as checked; they do not imply withdrawal or safety. No reader inventory is sent.","generation":"enrichment-d0adb98f65b04a798dd6ab08fb972092","complete":false,"records":13666,"lastAttemptAt":"2026-11-08T13:04:49.0861553+00:00","lastSuccessAt":"2026-11-08T13:04:49.083+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:49.083+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13185,"expectedIdentifiers":13706,"failedIdentifiers":0},{"source":"osv:Go","scope":"Complete OSV Go ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"go-980593e6977a6d1b4fb1eed5a1ffe88a468736f89f0a06f710924ad59132c023","complete":true,"records":9914,"lastAttemptAt":"2026-11-08T13:04:23.3678903+00:00","lastSuccessAt":"2026-11-08T11:07:07.068788+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:23.3678903+00:00","snapshotPublishedAt":"2026-11-08T11:02:46+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-fde804134ecdda0ddd5ff5c26ee1fff5a6fa659311f7ef2e51c6ad54964db0e2","complete":true,"records":1971,"lastAttemptAt":"2026-11-08T13:04:23.1502223+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:23.1502223+00:00","snapshotPublishedAt":"2026-11-06T18:17:57+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:crates.io","scope":"Complete OSV crates.io ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"crates.io-964c14035e6f0f6478b2870fad6a7ef9f6045876d4a12af2c2e514521e54b6af","complete":true,"records":3055,"lastAttemptAt":"2026-11-08T13:04:23.4767311+00:00","lastSuccessAt":"2026-11-08T11:07:12.1927025+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:23.4767311+00:00","snapshotPublishedAt":"2026-11-08T11:02:46+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null},{"source":"osv:npm","scope":"Complete OSV npm ecosystem archive, including withdrawn and malicious-package source records; statement counts are not unique CVE counts","generation":"npm-f8647d7ba64b1ba0dfdc7130944766d5b36d5b77d18fff0c79e651a4cff3c2b9","complete":true,"records":231293,"lastAttemptAt":"2026-11-08T13:04:23.2659134+00:00","lastSuccessAt":"2026-11-08T11:06:56.2918717+00:00","error":null,"lastVerifiedAt":"2026-11-08T13:04:23.2659134+00:00","snapshotPublishedAt":"2026-11-08T11:02:50+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}