CVE-2026-73425: @astrojs/netlify @astrojs/netlify Generates An Overly-broad Netlify Vulnerability

LOW
Advisory Identifier: GHSA-hp3v-mfqw-h74c
CVSS 3.7
CWE-185
Published
Advisory Summary

CVE-2026-73425 is a LOW (CVSS 3.7) @astrojs/netlify generates an overly-broad netlify vulnerability (CWE-185: Incorrect Regular Expression) affecting @astrojs/netlify libraries in the npm ecosystem. The issue involves @astrojs/netlify generates an overly-broad netlify image cdn allowlist because remotepatterns.pathname metacharacters are not escaped. Remediation is available by upgrading affected packages to version 8.1.2.

CVE-2026-73425 at a Glance

CVE Identifier CVE-2026-73425
GHSA Identifier GHSA-hp3v-mfqw-h74c
Severity LOW
CVSS v3.1 Base Score 3.7
CWE Classification CWE-185: Incorrect Regular Expression
Affected Product @astrojs/netlify
Package Ecosystem npm
Published Date
Last Updated

Security Impact

CVSS: 3.7

The security impact metrics below are parsed directly from the CVSS v3.1 vector string (CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N).

Attack Vector Network (AV:N)
Attack Complexity High (AC:H)
Privileges Required None (PR:N)
User Interaction None (UI:N)
Scope Unchanged (S:U)
Confidentiality Low (C:L)
Integrity None (I:N)
Availability None (A:N)

How to Fix CVE-2026-73425

To remediate this vulnerability, upgrade all affected @astrojs/netlify dependencies to a patched release. Both direct and transitive dependencies should be checked, as frameworks or security libraries may pull in vulnerable versions transitively.

@astrojs/netlify fixed: 8.1.2
npm install @astrojs/netlify@8.1.2
Verify Direct and Transitive Dependencies

Run the following command in your project directory to verify that all resolved dependencies use the patched release:

npm ls @astrojs/netlify

How to Check if You Are Affected

To determine whether your Node.js application is affected by CVE-2026-73425, inspect your project dependencies using npm:

npm ls @astrojs/netlify

Analyze the terminal output to locate any version of @astrojs/netlify in your dependency tree. If any resolved version matches the vulnerable ranges listed in the table below (for example, versions earlier than 8.1.2), your application is affected.

Note: The npm ls @astrojs/netlify command inspects dependencies declared in your package.json and lockfile; it does not perform automated runtime dynamic scanning.

Technical Details

Vulnerability Mechanism & Technical Analysis

This vulnerability is classified under CWE-185: Incorrect Regular Expression, where the product specifies a regular expression in a way that causes data to be improperly matched or compared. In @astrojs/netlify, software state validation or input boundaries are circumvented during processing. Review the official source advisory statement below for specific affected components, classes, and reproduction details.

Source Advisory Statement

## Summary The `@astrojs/netlify` adapter converts each `image.remotePatterns` entry into a regular expression that is written to `.netlify/v1/config.json` under `images.remote_images`. Netlify's Image CDN uses these regexes as the allowlist that decides which remote image URLs it will optimize. `remotePatternToRegex()` escapes `.` in the hostname but interpolates the literal `pathname` into the regex **without escaping regex metacharacters**. As a result, the generated allowlist is broader than the pattern the developer declared, and broader than Astro's canonical `matchPattern()` helper (which compares non-wildcard pathnames by exact string equality). This is a residual of the same bug class addressed in CVE-2026-54300 (PR #17018, commit `1310277d`). That fix corrected wildcard semantics and added a `$` anchor but did not add metacharacter escaping for literal pathnames. ## Details In `packages/integrations/netlify/src/index.ts`, `remotePatternToRegex()` escapes dots in the hostname: ```js regexStr += hostname.replace(/\./g, '\\.'); ``` but interpolates the pathname unescaped in all three branches, e.g. the exact-match branch: ```js regexStr += `(\\${pathname})`; ``` Any regex metacharacter in the literal path (`.`, `+`, `?`, `(`, `[`, ...) is therefore passed through raw. Because `.` matches any character (including `/`), a restrictive pattern is silently widened. The security boundary on Netlify is the generated regex itself — Netlify's Image CDN enforces it directly and Astro's runtime `matchPattern()` is not in the loop for this path, so there is no compensating layer that re-validates the request. ## Proof of Concept Configure an SSR site with a literal pathname containing a `.`: ```js // astro.config.mjs image: { remotePatterns: [{ protocol: 'https', hostname: 'cdn.example.com', pathname: '/img/v1.0/file', }], } ``` Run `astro build` and inspect `.netlify/v1/config.json` `images.remote_images[0]`: ``` https://cdn\.example\.com(:[0-9]+)?(\/img/v1.0/file)([?][^#]*)?$ ``` Testing the generated regex: - `https://cdn.example.com/img/v1.0/file` -> MATCH (intended) - `https://cdn.example.com/img/v1X0/file` -> MATCH (bypass; the unescaped `.` matches any character) - `https://cdn.example.com/img/v1/0/file` -> MATCH (bypass; `.` also matches `/`, crossing a path segment) Astro's canonical `matchPattern()` (exact string equality on the pathname) rejects both bypass URLs. ## Impact Netlify's Image CDN accepts optimization requests for URLs on the allowed host that the developer's `remotePatterns` entry was intended to exclude. The hostname remains correctly anchored, so the broadening is confined to the pathname dimension on an already-allowed host. Realistic impact depends on whether other images the developer meant to keep out of their CDN exist at metacharacter-adjacent paths on that host. This affects reasonable, non-permissive configurations, since any `pathname` containing a `.` (file extensions, version segments) is affected. ## Patches A fix will escape all regex metacharacters in the literal portions of each `remotePatterns` component before interpolation, applying only Astro's documented wildcard semantics explicitly. A regression corpus validates the generated Netlify regexes against `@astrojs/internal-helpers`' `matchPattern()`. ## Workarounds Avoid regex metacharacters (notably `.`) in `image.remotePatterns[].pathname` values, or scope the allowed host so that unintended paths are not reachable. ## Credit Reported by @sec-reex as part of an incomplete-patch measurement study (responsible disclosure).

CVE-2026-73425 Affected @astrojs/netlify Versions

1 component(s)
Fixed Versions:
8.1.2
Product / Package Ecosystem Affected Versions Fixed Version
@astrojs/netlify
npm
< 8.1.2
8.1.2

References

Frequently Asked Questions

What is CVE-2026-73425?
CVE-2026-73425 is a security vulnerability in @astrojs/netlify involving @astrojs/netlify generates an overly-broad Netlify Image CDN allowlist because remotePatterns.pathname metacharacters are not escaped under CWE-185: Incorrect Regular Expression.
Which @astrojs/netlify versions are affected?
Affected versions include releases prior to 8.1.2 across affected packages: @astrojs/netlify.
What version fixes CVE-2026-73425?
Upgrading to 8.1.2 (or the latest patched release for your respective branch) resolves the vulnerability.
Is @astrojs/netlify affected?
Yes, @astrojs/netlify is affected in releases prior to 8.1.2. Upgrade your dependency to 8.1.2 or later.
What is the CVSS score of CVE-2026-73425?
CVE-2026-73425 has a CVSS v3.1 base score of 3.7 (LOW) with vector string CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N.
What CWE is associated with CVE-2026-73425?
CVE-2026-73425 is classified under CWE-185: Incorrect Regular Expression (The product specifies a regular expression in a way that causes data to be improperly matched or compared.).
How can I check npm dependencies for CVE-2026-73425?
Run the dependency tree command: 'npm ls @astrojs/netlify'. This command lists direct and transitive dependencies in your build configuration so you can verify if a vulnerable version is resolved.
Machine-readable OSV JSON OSV v1.5 Schema
Normalized schema output
{
  "schema_version" : "1.4.0",
  "id" : "GHSA-hp3v-mfqw-h74c",
  "modified" : "2026-08-13T15:18:37Z",
  "published" : "2026-07-20T23:24:34Z",
  "aliases" : [ "CVE-2026-73425" ],
  "summary" : "@astrojs/netlify generates an overly-broad Netlify Image CDN allowlist because remotePatterns.pathname metacharacters are not escaped",
  "details" : "## Summary\n\nThe `@astrojs/netlify` adapter converts each `image.remotePatterns` entry into a regular expression that is written to `.netlify/v1/config.json` under `images.remote_images`. Netlify's Image CDN uses these regexes as the allowlist that decides which remote image URLs it will optimize. `remotePatternToRegex()` escapes `.` in the hostname but interpolates the literal `pathname` into the regex **without escaping regex metacharacters**. As a result, the generated allowlist is broader than the pattern the developer declared, and broader than Astro's canonical `matchPattern()` helper (which compares non-wildcard pathnames by exact string equality).\n\nThis is a residual of the same bug class addressed in CVE-2026-54300 (PR #17018, commit `1310277d`). That fix corrected wildcard semantics and added a `$` anchor but did not add metacharacter escaping for literal pathnames.\n\n## Details\n\nIn `packages/integrations/netlify/src/index.ts`, `remotePatternToRegex()` escapes dots in the hostname:\n\n```js\nregexStr += hostname.replace(/\\./g, '\\\\.');\n```\n\nbut interpolates the pathname unescaped in all three branches, e.g. the exact-match branch:\n\n```js\nregexStr += `(\\\\${pathname})`;\n```\n\nAny regex metacharacter in the literal path (`.`, `+`, `?`, `(`, `[`, ...) is therefore passed through raw. Because `.` matches any character (including `/`), a restrictive pattern is silently widened.\n\nThe security boundary on Netlify is the generated regex itself — Netlify's Image CDN enforces it directly and Astro's runtime `matchPattern()` is not in the loop for this path, so there is no compensating layer that re-validates the request.\n\n## Proof of Concept\n\nConfigure an SSR site with a literal pathname containing a `.`:\n\n```js\n// astro.config.mjs\nimage: {\n  remotePatterns: [{\n    protocol: 'https',\n    hostname: 'cdn.example.com',\n    pathname: '/img/v1.0/file',\n  }],\n}\n```\n\nRun `astro build` and inspect `.netlify/v1/config.json` `images.remote_images[0]`:\n\n```\nhttps://cdn\\.example\\.com(:[0-9]+)?(\\/img/v1.0/file)([?][^#]*)?$\n```\n\nTesting the generated regex:\n\n- `https://cdn.example.com/img/v1.0/file` -> MATCH (intended)\n- `https://cdn.example.com/img/v1X0/file` -> MATCH (bypass; the unescaped `.` matches any character)\n- `https://cdn.example.com/img/v1/0/file` -> MATCH (bypass; `.` also matches `/`, crossing a path segment)\n\nAstro's canonical `matchPattern()` (exact string equality on the pathname) rejects both bypass URLs.\n\n## Impact\n\nNetlify's Image CDN accepts optimization requests for URLs on the allowed host that the developer's `remotePatterns` entry was intended to exclude. The hostname remains correctly anchored, so the broadening is confined to the pathname dimension on an already-allowed host. Realistic impact depends on whether other images the developer meant to keep out of their CDN exist at metacharacter-adjacent paths on that host. This affects reasonable, non-permissive configurations, since any `pathname` containing a `.` (file extensions, version segments) is affected.\n\n## Patches\n\nA fix will escape all regex metacharacters in the literal portions of each `remotePatterns` component before interpolation, applying only Astro's documented wildcard semantics explicitly. A regression corpus validates the generated Netlify regexes against `@astrojs/internal-helpers`' `matchPattern()`.\n\n## Workarounds\n\nAvoid regex metacharacters (notably `.`) in `image.remotePatterns[].pathname` values, or scope the allowed host so that unintended paths are not reachable.\n\n## Credit\n\nReported by @sec-reex as part of an incomplete-patch measurement study (responsible disclosure).",
  "severity" : [ {
    "type" : "CVSS_V3",
    "score" : "CVSS:3.1/AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:N/A:N"
  } ],
  "affected" : [ {
    "package" : {
      "ecosystem" : "npm",
      "name" : "@astrojs/netlify"
    },
    "ranges" : [ {
      "type" : "ECOSYSTEM",
      "events" : [ {
        "introduced" : "0"
      }, {
        "fixed" : "8.1.2"
      } ]
    } ]
  } ],
  "references" : [ {
    "type" : "WEB",
    "url" : "https://github.com/withastro/astro/security/advisories/GHSA-hp3v-mfqw-h74c"
  }, {
    "type" : "ADVISORY",
    "url" : "https://nvd.nist.gov/vuln/detail/CVE-2026-73425"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/withastro/astro/pull/17018"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/withastro/astro/pull/17368"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/withastro/astro/commit/ee74c289bfe32fb6a7f59ed97c5c22db16394b72"
  }, {
    "type" : "ADVISORY",
    "url" : "https://github.com/advisories/GHSA-529g-xq4f-cw38"
  }, {
    "type" : "PACKAGE",
    "url" : "https://github.com/withastro/astro"
  }, {
    "type" : "WEB",
    "url" : "https://github.com/withastro/astro/releases/tag/@astrojs/netlify@8.1.2"
  } ],
  "database_specific" : {
    "cwe_ids" : [ "CWE-185" ],
    "severity" : "LOW",
    "github_reviewed" : true,
    "github_reviewed_at" : "2026-07-20T23:24:34Z",
    "nvd_published_at" : "2026-08-12T21:17:41Z"
  }
}