From 5d126c7806f58951f339b7cf90bb6c552c060191 Mon Sep 17 00:00:00 2001 From: Gabe Rodriguez Date: Wed, 26 Jun 2024 14:18:21 +0200 Subject: [PATCH] Guard against bad default frontends (#61) * Guard against bad default frontends * review update --- .../src/shared/utils/is-valid-url.test.ts | 31 +++++++++++++++++++ .../src/shared/utils/is-valid-url.ts | 7 +++-- 2 files changed, 36 insertions(+), 2 deletions(-) create mode 100644 apps/extension/src/shared/utils/is-valid-url.test.ts diff --git a/apps/extension/src/shared/utils/is-valid-url.test.ts b/apps/extension/src/shared/utils/is-valid-url.test.ts new file mode 100644 index 00000000..fd59c135 --- /dev/null +++ b/apps/extension/src/shared/utils/is-valid-url.test.ts @@ -0,0 +1,31 @@ +import { describe, it, expect } from 'vitest'; +import { isValidUrl } from './is-valid-url'; + +describe('isValidUrl', () => { + it('should return true for valid http URLs', () => { + expect(isValidUrl('http://example.com')).toBe(true); + expect(isValidUrl('http://www.example.com')).toBe(true); + expect(isValidUrl('http://example.com/path')).toBe(true); + expect(isValidUrl('http://example.com?q=query')).toBe(true); + }); + + it('should return true for valid https URLs', () => { + expect(isValidUrl('https://example.com')).toBe(true); + expect(isValidUrl('https://www.example.com')).toBe(true); + expect(isValidUrl('https://example.com/path')).toBe(true); + expect(isValidUrl('https://example.com?q=query')).toBe(true); + }); + + it('should return false for URLs with unsupported protocols', () => { + expect(isValidUrl('ftp://example.com')).toBe(false); + expect(isValidUrl('mailto:someone@example.com')).toBe(false); + expect(isValidUrl('chrome-extension://lkpmkhpnhknhmibgnmmhdhgdilepfghe/page.html')).toBe(false); + }); + + it('should return false for strings that are not URLs', () => { + expect(isValidUrl('justastring')).toBe(false); + expect(isValidUrl('www.example.com')).toBe(false); + expect(isValidUrl('12345')).toBe(false); + expect(isValidUrl('')).toBe(false); + }); +}); diff --git a/apps/extension/src/shared/utils/is-valid-url.ts b/apps/extension/src/shared/utils/is-valid-url.ts index adee0bef..18b87f16 100644 --- a/apps/extension/src/shared/utils/is-valid-url.ts +++ b/apps/extension/src/shared/utils/is-valid-url.ts @@ -1,7 +1,10 @@ export const isValidUrl = (url: string) => { try { - new URL(url); - return true; + const proposedUrl = new URL(url); + + // Security measure: allows us to guard against someone being deceived + // into adding a url with chrome-extension:// in it with intentions to inject code + return ['https:', 'http:'].includes(proposedUrl.protocol); } catch { return false; }