Skip to content

Commit 239aa4d

Browse files
Validate cookie protocol and header names
1 parent 090044e commit 239aa4d

2 files changed

Lines changed: 45 additions & 20 deletions

File tree

src/background/index.mjs

Lines changed: 43 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -714,10 +714,11 @@ Browser.runtime.onMessage.addListener(async (message, sender) => {
714714
break
715715
case 'PIN_TAB': {
716716
console.log('[background] Processing PIN_TAB message:', message.data)
717-
let tabId = message.data.tabId ?? sender.tab?.id
717+
const data = message.data ?? {}
718+
let tabId = data.tabId ?? sender.tab?.id
718719
if (tabId) {
719720
await Browser.tabs.update(tabId, { pinned: true })
720-
if (message.data.saveAsChatgptConfig) {
721+
if (data.saveAsChatgptConfig) {
721722
console.debug('[background] Saving pinned tab as ChatGPT config tab:', tabId)
722723
await setUserConfig({ chatgptTabId: tabId })
723724
}
@@ -744,20 +745,28 @@ Browser.runtime.onMessage.addListener(async (message, sender) => {
744745
console.warn('[background] Invalid FETCH input:', message.data?.input)
745746
return [null, { message: 'Invalid fetch input' }]
746747
}
747-
if (!fetchInput.startsWith('https://') && !fetchInput.startsWith('http://')) {
748-
console.warn('[background] Rejecting FETCH for non-http(s) URL:', fetchInput)
749-
return [null, { message: 'Unsupported fetch protocol' }]
748+
let validatedUrl
749+
try {
750+
const url = new URL(fetchInput)
751+
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
752+
console.warn('[background] Rejecting FETCH for non-http(s) URL:', fetchInput)
753+
return [null, { message: 'Unsupported fetch protocol' }]
754+
}
755+
validatedUrl = url.toString()
756+
} catch (error) {
757+
console.warn('[background] Invalid FETCH input URL:', fetchInput, error)
758+
return [null, { message: 'Invalid fetch URL' }]
750759
}
751760

752-
console.log('[background] Processing FETCH message for URL:', fetchInput)
753-
if (fetchInput.includes('bing.com')) {
761+
console.log('[background] Processing FETCH message for URL:', validatedUrl)
762+
if (validatedUrl.includes('bing.com')) {
754763
console.debug('[background] Fetching Bing access token for FETCH message.')
755764
const accessToken = await getBingAccessToken()
756765
await setUserConfig({ bingAccessToken: accessToken })
757766
}
758767

759768
try {
760-
const response = await fetch(fetchInput, message.data?.init)
769+
const response = await fetch(validatedUrl, message.data?.init)
761770
const text = await response.text()
762771
const responseObject = {
763772
// Defined for clarity before conditional error property
@@ -770,15 +779,15 @@ Browser.runtime.onMessage.addListener(async (message, sender) => {
770779
if (!response.ok) {
771780
responseObject.error = `HTTP error ${response.status}: ${response.statusText}`
772781
console.warn(
773-
`[background] FETCH received error status: ${response.status} for ${fetchInput}`,
782+
`[background] FETCH received error status: ${response.status} for ${validatedUrl}`,
774783
)
775784
}
776785
console.debug(
777-
`[background] FETCH successful for ${fetchInput}, status: ${response.status}`,
786+
`[background] FETCH successful for ${validatedUrl}, status: ${response.status}`,
778787
)
779788
return [responseObject, null]
780789
} catch (error) {
781-
console.error(`[background] FETCH error for ${fetchInput}:`, error)
790+
console.error(`[background] FETCH error for ${validatedUrl}:`, error)
782791
return [null, { message: error.message }]
783792
}
784793
}
@@ -808,6 +817,13 @@ Browser.runtime.onMessage.addListener(async (message, sender) => {
808817
console.warn('[background] Rejecting GET_COOKIE with invalid URL:', cookieUrlInput)
809818
return null
810819
}
820+
if (cookieUrl.protocol !== 'http:' && cookieUrl.protocol !== 'https:') {
821+
console.warn(
822+
'[background] Rejecting GET_COOKIE with disallowed protocol:',
823+
cookieUrl.protocol,
824+
)
825+
return null
826+
}
811827

812828
const cookieName = cookieNameInput.trim()
813829
console.debug('[background] Processing GET_COOKIE message for:', cookieUrl.href)
@@ -905,20 +921,24 @@ try {
905921
const headers = details.requestHeaders
906922
let modified = false
907923
for (let i = 0; i < headers.length; i++) {
908-
if (!headers[i]) {
924+
const header = headers[i]
925+
if (!header || !header.name) {
909926
continue
910927
}
911-
const headerNameLower = headers[i].name?.toLowerCase()
928+
const headerNameLower = header.name.toLowerCase()
912929
if (headerNameLower === 'origin') {
913-
headers[i].value = 'https://www.bing.com'
930+
header.value = 'https://www.bing.com'
914931
modified = true
915932
} else if (headerNameLower === 'referer') {
916-
headers[i].value = 'https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx'
933+
header.value = 'https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx'
917934
modified = true
918935
}
919936
}
920937
if (modified) {
921-
console.debug('[background] Modified headers for Bing:', headers)
938+
console.debug(
939+
'[background] Modified headers for Bing (names only):',
940+
headers.map((header) => header?.name).filter(Boolean),
941+
)
922942
}
923943
return { requestHeaders: headers }
924944
} catch (error) {
@@ -941,11 +961,15 @@ try {
941961
(details) => {
942962
const headers = details.requestHeaders
943963
for (let i = 0; i < headers.length; i++) {
944-
const headerNameLower = headers[i]?.name?.toLowerCase()
964+
const header = headers[i]
965+
if (!header || !header.name) {
966+
continue
967+
}
968+
const headerNameLower = header.name.toLowerCase()
945969
if (headerNameLower === 'origin') {
946-
headers[i].value = 'https://claude.ai'
970+
header.value = 'https://claude.ai'
947971
} else if (headerNameLower === 'referer') {
948-
headers[i].value = 'https://claude.ai'
972+
header.value = 'https://claude.ai'
949973
}
950974
}
951975
return { requestHeaders: headers }

src/manifest.v2.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
"unlimitedStorage",
1717
"tabs",
1818
"webRequest",
19+
"webRequestBlocking",
1920
"https://*.chatgpt.com/*",
2021
"https://*.openai.com/",
2122
"https://*.bing.com/",
@@ -87,4 +88,4 @@
8788
"description": "Close all chats in this page"
8889
}
8990
}
90-
}
91+
}

0 commit comments

Comments
 (0)