GHSA-HP3V-MFQW-H74C: Netlify remotePatterns regex hardening is a Partial fix
Summary
The patch tightens wildcard hostname semantics and adds an end-of-string anchor to the generated regex for Netlify Image CDN remotePatterns. This closes concrete bypasses where apex hosts matched subdomain-only patterns and where prefix matches allowed deeper paths than intended. However, the advisory describes missing escaping of regex metacharacters in developer-supplied pathnames, and the provided patch snippets do not show comprehensive escaping of pathname literals before regex construction. Based on the supplied sources, the change improves matching correctness but does not fully demonstrate elimination of the root cause.
Analysis
Vulnerability
The issue in @astrojs/netlify is that developer-defined remotePatterns are compiled into regex used by Netlify Image CDN configuration, but pathname content was not safely constrained. The advisory states that dots and other regex metacharacters in configured pathnames were not escaped, which can broaden the effective match set and allow requests outside the intended path restriction boundary. In practice, this turns a declarative allowlist into a regex with attacker-relevant semantics, enabling bypass of path-level restrictions when the generated expression is evaluated by the edge layer. See the advisory and patch discussion: GitHub Security Advisory, pull request, and report summary.
The supplied code snippets also show two concrete regex correctness flaws beyond escaping: wildcard subdomain handling was too permissive, and the generated regex was not anchored to the end of the string. Those defects permit unintended matches even when the configured pattern appears narrower.
// vulnerable behavior from supplied snippets
// match any number of subdomains
regexStr += '([a-z0-9-]+\\.)*';
// match one subdomain
regexStr += '([a-z0-9-]+\\.)?';
// no end-of-string anchor shown, so .test() can match prefixesPatch
The patch makes two source-visible hardening changes in packages/integrations/netlify/src/index.ts from the referenced pull request. First, wildcard hostname semantics are tightened so *.example.org requires at least one subdomain rather than optionally matching the apex host. Second, the generated regex is anchored with $ so .test() cannot succeed on a valid prefix while ignoring trailing path content. The associated tests were updated to assert that the apex hostname no longer matches a subdomain-only pattern and that deeper paths do not match a single-segment wildcard path. The changeset describes this as stricter matching of canonical wildcard semantics. Source: pull request.
// patched behavior from supplied snippets
// match one or more subdomains
regexStr += '([a-z0-9-]+\\.)+';
// match exactly one subdomain
regexStr += '([a-z0-9-]+\\.)';
} else if (pathname.endsWith('/*')) {
// Anchor to end of string so .test() can't match a prefix
regexStr += '$';The test updates directly validate the intended narrowing:
assert.equal(
patterns.test('https://example.org/images/1.jpg'),
false,
'apex hostname should not match for *.example.org',
);
assert.equal(
patterns.test('https://www.example.org/images/a/b.jpg'),
false,
'deeper path should not match for /images/*',
);Review
Pros
- Fixes a real regex matching bug by adding an end-of-string anchor, preventing prefix-only matches from authorizing deeper or longer paths than intended.
- Corrects wildcard hostname semantics so subdomain patterns no longer match the apex domain, reducing overbroad host authorization.
- Adds regression tests for both hostname and pathname overmatch cases, which materially improves confidence in the specific behaviors changed.
- The changeset explicitly frames the intent as stricter canonical wildcard semantics, which aligns with least-privilege matching.
Cons
- The advisory is specifically about missing escaping of regex metacharacters in developer-defined pathnames, but the supplied patch snippets do not show pathname literal escaping being added before regex construction.
- Because the visible changes focus on wildcard quantifiers and end anchoring, they appear to address symptom classes of overmatching rather than conclusively removing regex injection risk from arbitrary pathname characters.
- No supplied test demonstrates that metacharacters such as
.,+,(,),[, or?inside configured pathnames are escaped and treated literally. - If pathname segments are still interpolated into regex without escaping, crafted configuration values could continue to alter match semantics despite the new anchor.
Verdict
Partial fix.
Based on the provided sources, the patch clearly hardens two important overmatch vectors: subdomain wildcard handling and end anchoring. Those changes close concrete bypasses demonstrated by the new tests. However, the stated root issue in the advisory is failure to escape regex metacharacters in developer-supplied pathnames, and that remediation is not visible in the supplied diff excerpts. For that reason, this patch should be treated as an incomplete but valuable narrowing step unless the full pull request contains additional escaping logic not present in the provided snippets. Engineers should verify that all non-wildcard pathname content is regex-escaped before interpolation and add dedicated tests for literal metacharacter handling. References: GitHub Security Advisory, pull request, report summary.
Recommended Labs
Try this vulnerability pattern yourself with hands-on labs.
- Path Traversal II.js
Closest hands-on defensive fit for this advisory’s core lesson: attacker-controlled patterns can bypass pathname restrictions if matching and normalization are done incorrectly. This lab reinforces secure handling of file/path constraints, canonicalization, and defense-in-depth validation in JavaScript.
- Insecure Normalization.js
Useful for understanding how seemingly safe matching logic can be undermined by improper normalization and interpretation gaps. That maps well to this patch review, where generated matching rules became unsafe because special characters were not escaped before being embedded in pattern logic.
- Pollution.js
Good complementary lab for learning defensive validation of untrusted input crossing trust boundaries. While not regex-specific, it teaches how malformed or unexpected input shapes can subvert application assumptions, which is directly relevant when developer-supplied path patterns are transformed into security-sensitive rules.