Skip to content

Commit

Permalink
Revert "fix dynamic routes bypass (#24)" (#25)
Browse files Browse the repository at this point in the history
This reverts commit 5111170.
  • Loading branch information
zhongliang02 authored Nov 7, 2024
1 parent 5111170 commit 031f6a3
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 17 deletions.
12 changes: 0 additions & 12 deletions packages/validators/src/__tests__/url.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,6 @@ describe('UrlValidator with base URL', () => {
it('should not allow Next.js dynamic routes', () => {
expect(() => validator.parse('/[[x]]javascript:alert(1337)/[y]/[z]?x&y&z')).toThrow(UrlValidationError)
})

it('should not allow Next.js dynamic routes', () => {
expect(() =>
validator.parse('/[[x]x]]https://[y]y]//example.com/[[/[[x]x]]/y?x=[[x]&x]x&%2F[[x=[[/[[x]&y=[y]&y]y='),
).toThrow(UrlValidationError)
})

it('should not allow Next.js dynamic routes', () => {
expect(() => validator.parse('/[[x]x]]javascript:alert(1)%2F%2F/[[/[[x]x]]/y?x=[[x]&x]x&%2F[[x=[[/[[x]')).toThrow(
UrlValidationError,
)
})
})

describe('UrlValidator with invalid options', () => {
Expand Down
20 changes: 15 additions & 5 deletions packages/validators/src/url/utils.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { UrlValidationError } from '@/url/errors'
import { UrlValidatorWhitelist } from '@/url/options'

// regex from https://github.com/vercel/next.js/blob/8cb8edb686ec8ddf7e24c69545d11175fcb9df02/packages/next/src/shared/lib/router/utils/is-dynamic.ts#L7
const DYNAMIC_ROUTE_SEGMENT_REGEX = /\/\[[^/]+?\](?=\/|$)/
const DYNAMIC_ROUTE_SEGMENT_REGEX = /\[\[?([^\]]+)\]?\]/g
const IS_NOT_HOSTNAME_REGEX = /[^.]+\.[^.]+/g

export const resolveRelativeUrl = (url: string, baseOrigin?: URL): URL => {
Expand All @@ -27,8 +26,19 @@ export const resolveRelativeUrl = (url: string, baseOrigin?: URL): URL => {
return normalizedUrl
}

export const isDynamicRoute = (url: URL): boolean => {
return DYNAMIC_ROUTE_SEGMENT_REGEX.test(url.pathname)
/* As of Next.js 14.2.5, router.push() resolves dynamic routes using query parameters. */
const resolveNextDynamicRoute = (url: URL): URL => {
const pathname = url.pathname
const query = new URLSearchParams(url.search)
const resolvedPathname = pathname.replace(DYNAMIC_ROUTE_SEGMENT_REGEX, (_, name: string) => {
const value = query.get(name) || ''
query.delete(name)
return value
})

const result = new URL(url.href)
result.pathname = resolvedPathname
return result
}

export const isSafeUrl = (url: URL, whitelist: UrlValidatorWhitelist) => {
Expand All @@ -49,7 +59,7 @@ export const isSafeUrl = (url: URL, whitelist: UrlValidatorWhitelist) => {
}

// don't allow dynamic routes
if (isDynamicRoute(url)) {
if (resolveNextDynamicRoute(url).href !== url.href) {
return false
}
return true
Expand Down

0 comments on commit 031f6a3

Please sign in to comment.