fix: escape regex metacharacters in isURLAllowed pathname allow-list - #17237
Merged
Conversation
…16997) ### What? Escapes regex metacharacters in the `pathname` matching of `isURLAllowed` (the upload allow-list matcher) before compiling the pattern to a `RegExp`. Applied to both copies of the function (`packages/payload` and `packages/ui`) and adds a unit test. ### Why? `isURLAllowed` compiled an allow-list `pathname` pattern into a `RegExp` without escaping regex metacharacters, so a configured `.` matched any character — e.g. pattern `/files/report.json` also matched `/files/reportXjson`. The allow-list therefore accepted more URLs than configured. This matters because `isURLAllowed` gates whether an upload-related fetch **skips SSRF protection**: in `getFileFromURL.ts` / `getExternalFile.ts` an allow-list match (`pasteURL.allowList` / `skipSafeFetch`) uses a plain `fetch` instead of `safeFetch`. Over-broad `pathname` matching widens that boundary. The `hostname` field is required and matched exactly, so this is not a full cross-host SSRF bypass — it is a defense-in-depth / least-privilege weakening on an already-trusted (often internal) host. Separately, `**` was translated to `.*` *before* `*` was translated to `[^/]*`, so the `*` inside the freshly inserted `.*` was rewritten again: `/uploads/**` compiled to `/uploads/.[^/]*` and failed to match `/uploads/nested/file.png` (fail-closed correctness bug). ### How? Escape the pattern first via the existing `escapeRegExp` utility (the same approach `wordBoundariesRegex.ts` already uses), then restore the now-escaped `\*\*` / `\*` wildcards. Escaping first also resolves the ordering bug, because the resulting `.*` no longer contains an escaped `\*` for the next replace to match: ```ts const regexPattern = escapeRegExp(value) .replace(/\\\*\\\*/g, '.*') // `**` → match any path .replace(/\\\*/g, '[^/]*') // `*` → match any part of a path segment .replace(/\/$/, '(/)?') // Allow optional trailing slash ``` Adds `packages/payload/src/utilities/isURLAllowed.spec.ts` covering literal metacharacters, `*` vs `**` segment semantics, exact hostname matching (incl. the `userinfo@host` case), and the optional trailing slash. Fixes #16996
r1tsuu
requested review from
AlessioGr,
JarrodMFlesch and
jacobsfletch
as code owners
July 8, 2026 11:27
Contributor
📦 esbuild Bundle Analysis for payloadThis analysis was generated by esbuild-bundle-analyzer. 🤖
Largest pathsThese visualization shows top 20 largest paths in the bundle.Meta file: packages/next/meta_index.json, Out file: esbuild/index.js
Meta file: packages/payload/meta_index.json, Out file: esbuild/index.js
Meta file: packages/payload/meta_shared.json, Out file: esbuild/exports/shared.js
Meta file: packages/richtext-lexical/meta_client.json, Out file: esbuild/exports/client_optimized/index.js
Meta file: packages/ui/meta_client.json, Out file: esbuild/exports/client_optimized/index.js
Meta file: packages/ui/meta_shared.json, Out file: esbuild/exports/shared_optimized/index.js
DetailsNext to the size is how much the size has increased or decreased compared with the base branch of this PR.
|
DanRibbens
approved these changes
Jul 8, 2026
Contributor
|
🚀 This is included in version v3.86.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Port of #16997 to
3.x