{"id":"CVE-2026-44589","revision":null,"records":[{"revision":"1fad39ab224b49b08bcb8045464b467c","observedAt":"2026-10-23T15:48:27.903+00:00","statement":{"source":"cve-program","id":"CVE-2026-44589","aliases":[],"title":"nuxt-og-image SSRF — bypass of GHSA-pqhr-mp3f-hrpp / v6.2.5 fix (IPv6 + redirect)","description":"Nuxt OG Image generates OG Images with Vue templates in Nuxt. The isBlockedUrl() denylist introduced in nuxt-og-image@6.2.5 to remediate GHSA-pqhr-mp3f-hrpp (Dmitry Prokhorov / Positive Technologies, March 2026) is incomplete. It has an incomplete IPv6 prefix list and is missing redirect re-validation. This vulnerability is fixed in 6.4.9.","state":0,"publishedAt":"2026-05-14T18:35:29.416+00:00","modifiedAt":"2026-05-14T19:51:03.306+00:00","affected":[{"ecosystem":"Vendor product","name":"og-image","ranges":[],"versions":[],"rawVersionEvidence":"{\n                    \"vendor\": \"nuxt-modules\",\n                    \"product\": \"og-image\",\n                    \"versions\": [\n                        {\n                            \"version\": \">= 6.2.5, < 6.4.9\",\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:L/I:N/A:N","score":3.7,"severity":"LOW"}],"references":["https://github.com/nuxt-modules/og-image/security/advisories/GHSA-c2rm-g55x-8hr5"],"sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-44589","license":"CVE Program Terms of Use","key":"cve-program:CVE-2026-44589","identifiers":["CVE-2026-44589"]},"retained":false,"historicalAffected":[]},{"revision":"a6139300943b42fba5d50bdc9f0f5fa2","observedAt":"2026-10-28T06:08:34.66+00:00","statement":{"source":"euvd","id":"EUVD-2026-30364","aliases":["CVE-2026-44589","GHSA-c2rm-g55x-8hr5"],"title":"Nuxt OG Image generates OG Images with Vue templates in Nuxt. The isBlockedUrl() denylist introduced in nuxt-og-image@6.2.5 to remediate GHSA-pqhr-mp3f-hrpp (Dmitry Prokhorov / Positive Technologies, March 2026) is incomplete. It has an inc…","description":"Nuxt OG Image generates OG Images with Vue templates in Nuxt. The isBlockedUrl() denylist introduced in nuxt-og-image@6.2.5 to remediate GHSA-pqhr-mp3f-hrpp (Dmitry Prokhorov / Positive Technologies, March 2026) is incomplete. It has an incomplete IPv6 prefix list and is missing redirect re-validation. This vulnerability is fixed in 6.4.9.","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:L/I:N/A:N","score":3.7,"severity":null}],"references":["https://github.com/nuxt-modules/og-image/security/advisories/GHSA-c2rm-g55x-8hr5"],"sourceUrl":"https://euvd.enisa.europa.eu/vulnerability/EUVD-2026-30364","license":"ENISA EUVD · source terms and attribution apply","enrichment":{"sourceStatus":null,"weaknesses":[],"productCriteria":[],"sourceDates":{"datePublished":"May 14, 2026, 6:35:29 PM","dateUpdated":"May 14, 2026, 7:51:03 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-30364","identifiers":["EUVD-2026-30364","CVE-2026-44589","GHSA-c2rm-g55x-8hr5"]},"retained":false,"historicalAffected":[]},{"revision":"268328181da447a7befeaf84f0d14c6d","observedAt":"2026-10-27T11:12:17.434+00:00","statement":{"source":"nvd","id":"CVE-2026-44589","aliases":[],"title":"Nuxt OG Image generates OG Images with Vue templates in Nuxt. The isBlockedUrl() denylist introduced in nuxt-og-image@6.2.5 to remediate GHSA-pqhr-mp3f-hrpp (Dmitry Prokhorov / Positive Technologies, March 2026) is incomplete. It has an inc…","description":"Nuxt OG Image generates OG Images with Vue templates in Nuxt. The isBlockedUrl() denylist introduced in nuxt-og-image@6.2.5 to remediate GHSA-pqhr-mp3f-hrpp (Dmitry Prokhorov / Positive Technologies, March 2026) is incomplete. It has an incomplete IPv6 prefix list and is missing redirect re-validation. This vulnerability is fixed in 6.4.9.","state":0,"publishedAt":"2026-05-14T19:16:38.007+00:00","modifiedAt":"2026-10-26T14:10:00.13+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:L/I:N/A:N","score":3.7,"severity":"LOW"}],"references":["https://github.com/nuxt-modules/og-image/security/advisories/GHSA-c2rm-g55x-8hr5"],"sourceUrl":"https://nvd.nist.gov/vuln/detail/CVE-2026-44589","license":"NIST NVD usage terms; underlying source attribution retained","enrichment":{"sourceStatus":"Deferred","weaknesses":["CWE-918"],"productCriteria":[],"sourceDates":{"published":"2026-05-14T19:16:38.007","lastModified":"2026-10-26T14:10:00.130"},"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-44589","identifiers":["CVE-2026-44589"]},"retained":false,"historicalAffected":[]},{"revision":"4ba12ae6fa6b40959f2f106cad088d8f","observedAt":"2026-10-24T13:17:17.793+00:00","statement":{"source":"osv","id":"GHSA-c2rm-g55x-8hr5","aliases":["CVE-2026-44589"],"title":"nuxt-og-image SSRF — bypass of GHSA-pqhr-mp3f-hrpp / v6.2.5 fix (IPv6 + redirect)","description":"## Summary\n\nThe `isBlockedUrl()` denylist introduced in `nuxt-og-image@6.2.5` to remediate **GHSA-pqhr-mp3f-hrpp** (Dmitry Prokhorov / Positive Technologies, March 2026) is incomplete. The patch advisory states \"Decimal/hexadecimal IP encoding bypasses are also handled\" — that part is true (Node's WHATWG URL parser canonicalizes those forms before validation), but the v6.2.5 implementation misses two independent surfaces in the latest release `6.4.8`:\n\n1. **IPv6 prefix list is incomplete.** The IPv6 branch checks only `bare === \"::1\" || startsWith(\"fc\") || startsWith(\"fd\") || startsWith(\"fe80\")`. It misses:\n   - `[::ffff:7f00:1]` — IPv6-mapped IPv4 loopback in pure-hex form (RE_MAPPED_V4 regex requires dotted-quad). **Reaches 127.0.0.1 on a single-stack-IPv4 host with no other primitive needed.**\n   - `[fec0::/10]` (RFC 3879 site-local — deprecated but still routable on legacy networks)\n   - `[5f00::/16]` (RFC 9602 SRv6 SIDs)\n   - `[3fff::/20]` (RFC 9637 IPv6 documentation v2)\n   - `[64:ff9b:1::/48]` (RFC 8215 NAT64 local-use, including embedded IPv4 loopback `[64:ff9b:1::7f00:1]`)\n\n2. **No redirect re-validation.** `isBlockedUrl` runs once on the initial `<img src>`. The subsequent `$fetch(decodedSrc, ...)` (ofetch, default redirect-follow) follows 30x responses with no second-pass validation. Any allowed origin that returns a 302 to an internal IP — S3 redirect rules, GCS, Azure, CloudFront, any user-content CDN where the attacker can place a single redirect — completes the SSRF.\n\nThe net result is that the v6.2.5 SSRF advisory is bypassable in two distinct ways. The same root family as #29 / #38 (ipx) but in a **different code path with different gaps** — `nuxt-og-image` does not delegate to `ipx`, it ships its own validator, and that validator has fresh issues that survived the prior fix.\n\n## Affected\n\n| Package          | Version           | Role                                                |\n|------------------|-------------------|-----------------------------------------------------|\n| `nuxt-og-image`  | `6.4.8` (latest)  | default OG-image generator for Nuxt apps            |\n| `@nuxtjs/og-image` (alias) | same          | re-export, same code path                            |\n\nThe vulnerable code lives in `dist/runtime/server/og-image/core/plugins/imageSrc.js` and is enforced for every `<img src>` (and `style=\"background-image: url(...)\"`) inside an OG image component, on production builds (`!import.meta.dev`).\n\n## Vulnerable code (`imageSrc.js`, verbatim)\n\n```js\nfunction isPrivateIPv4(a, b) {\n  if (a === 127) return true;\n  if (a === 10) return true;\n  if (a === 172 && b >= 16 && b <= 31) return true;\n  if (a === 192 && b === 168) return true;\n  if (a === 169 && b === 254) return true;\n  if (a === 0) return true;\n  return false;\n}\nfunction isBlockedUrl(url) {\n  let parsed;\n  try { parsed = new URL(url); } catch { return true; }\n  if (parsed.protocol !== \"http:\" && parsed.protocol !== \"https:\") return true;\n  const hostname = parsed.hostname.toLowerCase();\n  const bare = hostname.replace(RE_IPV6_BRACKETS, \"\");\n  if (bare === \"localhost\" || bare.endsWith(\".localhost\")) return true;\n  const mappedV4 = bare.match(RE_MAPPED_V4);   // /^::ffff:(\\d+\\.\\d+\\.\\d+\\.\\d+)$/\n  const ip = mappedV4 ? mappedV4[1] : bare;\n  const parts = ip.split(\".\");\n  if (parts.length === 4 && parts.every((p) => RE_DIGIT_ONLY.test(p))) {\n    /* dotted-decimal IPv4 path */\n  }\n  if (RE_INT_IP.test(ip)) {\n    /* single-integer IPv4 path */\n  }\n  if (bare === \"::1\" || bare.startsWith(\"fc\") || bare.startsWith(\"fd\") || bare.startsWith(\"fe80\"))\n    return true;                                  // ← gap: only 4 IPv6 prefixes\n  return false;                                   // ← everything else is \"public\"\n}\n\n// Then:\nasync function doResolveSrcToBuffer(src, kind, ctx) {\n  ...\n  if (!import.meta.dev && isBlockedUrl(decodedSrc)) {\n    return { blocked: true };\n  }\n  const buffer = await $fetch(decodedSrc, {     // ← follows 30x by default\n    responseType: \"arrayBuffer\",\n    timeout: fetchTimeout,\n  });\n  ...\n}\n```\n\nTwo distinct issues:\n\n- **The IPv6 prefix list is hand-rolled** (`fc`, `fd`, `fe80`, `::1`) and inherits no taxonomy from `ipaddr.js` or any RFC table.\n- **`$fetch` is `ofetch`**, which wraps Node `fetch()` with default `redirect: \"follow\"`. The validator does not run on the redirect target.\n\n## Reproducer (verbatim, no host privilege)\n\nEnd-to-end test of `isBlockedUrl` on a corpus of internal-IP forms, paired with empirical `fetch()` confirming which forms actually reach loopback. Verbatim output:\n\n```\n  isBlockedUrl?  fetch reaches loopback?  url\n  -------------  -----------------------  ---\n  ✓ blocked      YES                      http://127.0.0.1:8765/             (control: dotted-decimal loopback)\n  ✓ blocked      YES                      http://localhost:8765/             (control)\n  ✓ blocked      no(ECONNREFUSED)         http://[::1]:8765/                 (control: IPv6 loopback)\n  ✓ blocked      no(EHOSTUNREACH)         http://169.254.169.254:8765/       (control: AWS IMDS)\n  ✓ blocked      YES                      http://2130706433:8765/            (control: decimal-int IPv4)\n  ✓ blocked      YES                      http://0x7f000001:8765/            (control: hex-int IPv4)\n  ✓ blocked      YES                      http://0177.0.0.1:8765/            (control: octal — URL parser canonicalizes)\n  ✓ blocked      YES                      http://127.1:8765/                 (control: shorthand — URL parser canonicalizes)\n\n  ✗ NOT blocked  YES                      http://[::ffff:7f00:1]:8765/       (BYPASS: IPv6-mapped, hex form)\n  ✗ NOT blocked  no(unreachable)          http://[fec0::1]:8765/             (BYPASS: RFC 3879 site-local)\n  ✗ NOT blocked  no(unreachable)          http://[5f00::1]:8765/             (BYPASS: RFC 9602 SRv6)\n  ✗ NOT blocked  no(unreachable)          http://[3fff::1]:8765/             (BYPASS: RFC 9637 docs)\n  ✗ NOT blocked  no(unreachable)          http://[64:ff9b:1::1]:8765/        (BYPASS: RFC 8215 NAT64)\n  ✗ NOT blocked  no(unreachable)          http://[64:ff9b:1::7f00:1]:8765/   (BYPASS: NAT64 + embedded loopback)\n```\n\nThe first six bypass rows say \"✗ NOT blocked\" — that is `isBlockedUrl` returning `false` (i.e., \"this URL is fine to fetch\") for each of those addresses. The \"fetch reaches loopback\" column shows that `[::ffff:7f00:1]` actually round-trips to 127.0.0.1 on a single-stack-IPv4 dev box; the four cluster ranges are unreachable on the dev box but succeed on dual-stack / k8s / NAT64 / SRv6 networks where any of these prefixes is internally bound.\n\nThe \"control\" rows confirm the bypass set is minimal — the validator catches the obvious cases. The bypasses are the cases the prefix list forgot.\n\n### Class 2: redirect amplifier\n\n`$fetch(url, { responseType: \"arrayBuffer\", timeout })` follows 30x by default. Confirmed empirically — `ofetch('http://lab.menna.website/test/redirect-to-loopback')` (where `lab.menna.website` returns `302 Location: http://127.0.0.1/`) ends with `<no response> fetch failed` after the connect attempt to `127.0.0.1:80`, proving the redirect was followed. On a target where the redirect destination has a service bound, the bytes round-trip back through the OG renderer.\n\nSame primitive as #29 / #38 (ipx redirect bypass), in a different validator. The fix recommendations for #29 also apply here, with the same trade-offs.\n\n## Impact\n\nA Nuxt application that uses `nuxt-og-image` (the official-recommended OG generator) and includes any user-influenced URL in an OG component is vulnerable to SSRF that returns the bytes of the internal response as part of the rendered OG image:\n\n- **Class 1 directly:** `<img src=\"http://[::ffff:7f00:1]:PORT/path\">` reaches 127.0.0.1 on the OG worker. If the dev's deployment has anything bound to loopback (admin dashboards, internal HTTP-RPC, Redis HTTP UI, anything running alongside the function on the same machine in self-hosted setups), it leaks.\n- **Class 1 cluster:** the IPv6 cluster ranges trigger only on dual-stack / k8s / NAT64 networks — but those are exactly the production targets where SSRF matters most.\n- **Class 2 redirect:** any allowed CDN with a redirect rule extends the reach to all RFC 1918 / loopback / link-local space.\n\n`nuxt-og-image` is the OG-image module recommended in Nuxt's official documentation; it is shipped with Nuxt UI templates and is one of the top-2 Nuxt modules by GitHub stars. The user-facing primitive in real apps is \"title/avatar comes from a request param\" — exactly the same `<NuxtLink to=\"/og?avatar=...\">` pattern Nuxt docs encourage.\n\n## Suggested fix\n\nThree non-exclusive options:\n\n1. **Replace the hand-rolled IPv6 prefix list with `ipaddr.js`'s `range()` predicate** (or equivalent), then either:\n   - explicitly deny the four cluster ranges that `ipaddr.js` currently misses (`fec0::/10`, `5f00::/16`, `3fff::/20`, `64:ff9b:1::/48`), or\n   - wait for the `ipaddr.js` upstream patch (see Vercel #27 — same gap, separately disclosed) and bump.\n   - In any case, also catch `[::ffff:7f00:1]` either by widening `RE_MAPPED_V4` or by classifying any `::ffff:` address as the embedded IPv4.\n\n2. **Pass `redirect: \"manual\"` in `$fetch` defaults** and reject 3xx. (Compare `astro:assets`, which already does this — `await fetch(url, { redirect: \"manual\" })` and explicit 3xx-rejection.)\n\n3. **Pin the validated IP to the connection.** Resolve the hostname once during validation, then pass a custom `undici.Agent` with `connect.lookup` returning the resolved IP only. This closes both the IPv6 bypass class (the resolved IP is checked again) and the redirect class (post-30x lookup is forced to the original IP). Reference: `request-filtering-agent` on npm.\n\n(2) alone closes Class 2. (1) alone closes Class 1. (3) closes both with one change.","state":0,"publishedAt":"2026-05-07T20:52:30+00:00","modifiedAt":"2026-05-16T00:06:28.251916+00:00","affected":[{"ecosystem":"npm","name":"nuxt-og-image","ranges":[{"type":"SEMVER","events":[{"kind":"introduced","version":"6.2.5"},{"kind":"fixed","version":"6.4.9"}]}],"versions":[],"rawVersionEvidence":null}],"metrics":[{"system":"CVSS_V3","vector":"CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N","score":null,"severity":null},{"system":"Publisher rating","vector":null,"score":null,"severity":"LOW"}],"references":["https://github.com/nuxt-modules/og-image/security/advisories/GHSA-c2rm-g55x-8hr5","https://nvd.nist.gov/vuln/detail/CVE-2026-44589","https://github.com/nuxt-modules/og-image"],"sourceUrl":"https://github.com/advisories/GHSA-c2rm-g55x-8hr5","license":"GitHub Advisory Database · CC-BY-4.0","key":"osv:GHSA-c2rm-g55x-8hr5","identifiers":["GHSA-c2rm-g55x-8hr5","CVE-2026-44589"]},"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-28T08:35:46.0321251+00:00","complete":true,"records":1760,"lastAttemptAt":"2026-10-28T08:35:46.0321251+00:00","lastSuccessAt":"2026-10-28T08:35:46.1809818+00:00","error":null,"lastVerifiedAt":"2026-10-28T08:35:46.1809834+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-d2186f400c54d65f61687f78bb1a00d184d2e215877d0194d7ed70caee809a44-ff4f74c3715c9a3496fe426269eeab8c293eb793d2258c3b1bc865401808b8dc","complete":true,"records":415607,"lastAttemptAt":"2026-10-28T08:33:51.7918726+00:00","lastSuccessAt":"2026-10-28T08:33:51.7534516+00:00","error":null,"lastVerifiedAt":"2026-10-28T08:33:51.7918726+00:00","snapshotPublishedAt":"2026-10-28T08:29:41+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-2841f7b33c6745c1830fd0029a563b0f","complete":false,"records":12672,"lastAttemptAt":"2026-10-28T08:47:27.9054091+00:00","lastSuccessAt":"2026-10-28T08:47:27.901+00:00","error":"21 identifier lookups failed; latest failures include HTTP 403. Other identifiers were checked independently.","lastVerifiedAt":"2026-10-28T08:47:27.901+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":7979,"expectedIdentifiers":13514,"failedIdentifiers":21},{"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-28T08:35:46.0321251+00:00","complete":true,"records":1093,"lastAttemptAt":"2026-10-28T08:35:46.0321251+00:00","lastSuccessAt":"2026-10-28T08:35:46.2951865+00:00","error":null,"lastVerifiedAt":"2026-10-28T08:35:46.2951876+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-8d16a738328646698f9217d8ea11893c","complete":true,"records":13449,"lastAttemptAt":"2026-10-28T08:35:46.9871249+00:00","lastSuccessAt":"2026-10-27T22:48:29.491+00:00","error":null,"lastVerifiedAt":"2026-10-27T22:48:29.491+00:00","snapshotPublishedAt":null,"importing":false,"stagedRecords":0,"checkedIdentifiers":13514,"expectedIdentifiers":13514,"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-f7cb12508d9e6a348c8a60f772ed85529cc80cd2ff853da1099b57754b20e943","complete":true,"records":9790,"lastAttemptAt":"2026-10-28T08:35:45.5921662+00:00","lastSuccessAt":"2026-10-27T21:49:03.9756799+00:00","error":null,"lastVerifiedAt":"2026-10-28T08:35:45.5921662+00:00","snapshotPublishedAt":"2026-10-27T21:48:11+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-72e5e79de0026dd0562d40734074a2236a06886643d67182b8381eaee757dbf7","complete":true,"records":1966,"lastAttemptAt":"2026-10-28T08:33:51.957016+00:00","lastSuccessAt":"2026-10-27T21:46:38.0277323+00:00","error":null,"lastVerifiedAt":"2026-10-28T08:33:51.957016+00:00","snapshotPublishedAt":"2026-10-27T21:18:15+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-3a5b306d60fc44677a03a8afc99d87e6c5402770ef68d560f94a8c3ad3802b75","complete":true,"records":3001,"lastAttemptAt":"2026-10-28T08:35:45.9903423+00:00","lastSuccessAt":"2026-10-27T16:45:49.0050993+00:00","error":null,"lastVerifiedAt":"2026-10-28T08:35:45.9903423+00:00","snapshotPublishedAt":"2026-10-27T16:33:43+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-e8b70aca15fb9881c8d03ced8f3c9cfecea26e693d496c6b1d8ab94175245b0c","complete":true,"records":230856,"lastAttemptAt":"2026-10-28T08:35:45.46342+00:00","lastSuccessAt":"2026-10-28T08:35:44.213519+00:00","error":null,"lastVerifiedAt":"2026-10-28T08:35:45.46342+00:00","snapshotPublishedAt":"2026-10-28T08:33:12+00:00","importing":false,"stagedRecords":0,"checkedIdentifiers":null,"expectedIdentifiers":null,"failedIdentifiers":null}]}