From 143a169cb77f01cb2b029f3da7b3fec32dbc2d6f Mon Sep 17 00:00:00 2001 From: andR3Scr1pTx86 <189578110+andR3Scr1pTx86@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:37:13 -0300 Subject: [PATCH 1/2] Adding another layer of validation for the URL with regex --- deno/lib/types.ts | 6 +++++- src/types.ts | 6 +++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/deno/lib/types.ts b/deno/lib/types.ts index cd09d4b15..d5043f644 100644 --- a/deno/lib/types.ts +++ b/deno/lib/types.ts @@ -640,6 +640,7 @@ const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i; // /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i; const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i; +const urlRegex = /^([a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*)(:\d+)?(\/[^\s,]*)?$/; const nanoidRegex = /^[a-z0-9_-]{21}$/i; const jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/; const durationRegex = @@ -918,7 +919,10 @@ export class ZodString extends ZodType { } } else if (check.kind === "url") { try { - new URL(input.data); + const parsed = new URL(input.data); + if (!urlRegex.test(parsed.host + parsed.pathname)) { + throw new Error(); + } } catch { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { diff --git a/src/types.ts b/src/types.ts index 98281ff2f..26e50eab8 100644 --- a/src/types.ts +++ b/src/types.ts @@ -640,6 +640,7 @@ const ulidRegex = /^[0-9A-HJKMNP-TV-Z]{26}$/i; // /^([a-f0-9]{8}-[a-f0-9]{4}-[1-5][a-f0-9]{3}-[a-f0-9]{4}-[a-f0-9]{12}|00000000-0000-0000-0000-000000000000)$/i; const uuidRegex = /^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/i; +const urlRegex = /^([a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*)(:\d+)?(\/[^\s,]*)?$/; const nanoidRegex = /^[a-z0-9_-]{21}$/i; const jwtRegex = /^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*$/; const durationRegex = @@ -918,7 +919,10 @@ export class ZodString extends ZodType { } } else if (check.kind === "url") { try { - new URL(input.data); + const parsed = new URL(input.data); + if (!urlRegex.test(parsed.host + parsed.pathname)) { + throw new Error(); + } } catch { ctx = this._getOrReturnCtx(input, ctx); addIssueToContext(ctx, { From fe4ddf04fe15df4b5a9fb5067acde43bf4ff4385 Mon Sep 17 00:00:00 2001 From: andR3Scr1pTx86 <189578110+andR3Scr1pTx86@users.noreply.github.com> Date: Wed, 18 Dec 2024 00:52:20 -0300 Subject: [PATCH 2/2] updating url validations test suite --- deno/lib/__tests__/string.test.ts | 1 + src/__tests__/string.test.ts | 1 + 2 files changed, 2 insertions(+) diff --git a/deno/lib/__tests__/string.test.ts b/deno/lib/__tests__/string.test.ts index bb967bafc..bd61c5bb5 100644 --- a/deno/lib/__tests__/string.test.ts +++ b/deno/lib/__tests__/string.test.ts @@ -297,6 +297,7 @@ test("url validations", () => { expect(() => url.parse("asdf")).toThrow(); expect(() => url.parse("https:/")).toThrow(); expect(() => url.parse("asdfj@lkjsdf.com")).toThrow(); + expect(() => url.parse("https://asdf.com,https://asdf")).toThrow(); }); test("url error overrides", () => { diff --git a/src/__tests__/string.test.ts b/src/__tests__/string.test.ts index bc603a933..1ca5fd7e5 100644 --- a/src/__tests__/string.test.ts +++ b/src/__tests__/string.test.ts @@ -296,6 +296,7 @@ test("url validations", () => { expect(() => url.parse("asdf")).toThrow(); expect(() => url.parse("https:/")).toThrow(); expect(() => url.parse("asdfj@lkjsdf.com")).toThrow(); + expect(() => url.parse("https://asdf.com,https://asdf")).toThrow(); }); test("url error overrides", () => {