Skip to content

Commit 0cfcb28

Browse files
Validate cookie protocol and header names
1 parent 1b701e9 commit 0cfcb28

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
@@ -687,10 +687,11 @@ Browser.runtime.onMessage.addListener(async (message, sender) => {
687687
break
688688
case 'PIN_TAB': {
689689
console.log('[background] Processing PIN_TAB message:', message.data)
690-
let tabId = message.data.tabId ?? sender.tab?.id
690+
const data = message.data ?? {}
691+
let tabId = data.tabId ?? sender.tab?.id
691692
if (tabId) {
692693
await Browser.tabs.update(tabId, { pinned: true })
693-
if (message.data.saveAsChatgptConfig) {
694+
if (data.saveAsChatgptConfig) {
694695
console.debug('[background] Saving pinned tab as ChatGPT config tab:', tabId)
695696
await setUserConfig({ chatgptTabId: tabId })
696697
}
@@ -717,20 +718,28 @@ Browser.runtime.onMessage.addListener(async (message, sender) => {
717718
console.warn('[background] Invalid FETCH input:', message.data?.input)
718719
return [null, { message: 'Invalid fetch input' }]
719720
}
720-
if (!fetchInput.startsWith('https://') && !fetchInput.startsWith('http://')) {
721-
console.warn('[background] Rejecting FETCH for non-http(s) URL:', fetchInput)
722-
return [null, { message: 'Unsupported fetch protocol' }]
721+
let validatedUrl
722+
try {
723+
const url = new URL(fetchInput)
724+
if (url.protocol !== 'https:' && url.protocol !== 'http:') {
725+
console.warn('[background] Rejecting FETCH for non-http(s) URL:', fetchInput)
726+
return [null, { message: 'Unsupported fetch protocol' }]
727+
}
728+
validatedUrl = url.toString()
729+
} catch (error) {
730+
console.warn('[background] Invalid FETCH input URL:', fetchInput, error)
731+
return [null, { message: 'Invalid fetch URL' }]
723732
}
724733

725-
console.log('[background] Processing FETCH message for URL:', fetchInput)
726-
if (fetchInput.includes('bing.com')) {
734+
console.log('[background] Processing FETCH message for URL:', validatedUrl)
735+
if (validatedUrl.includes('bing.com')) {
727736
console.debug('[background] Fetching Bing access token for FETCH message.')
728737
const accessToken = await getBingAccessToken()
729738
await setUserConfig({ bingAccessToken: accessToken })
730739
}
731740

732741
try {
733-
const response = await fetch(fetchInput, message.data?.init)
742+
const response = await fetch(validatedUrl, message.data?.init)
734743
const text = await response.text()
735744
const responseObject = {
736745
// Defined for clarity before conditional error property
@@ -743,15 +752,15 @@ Browser.runtime.onMessage.addListener(async (message, sender) => {
743752
if (!response.ok) {
744753
responseObject.error = `HTTP error ${response.status}: ${response.statusText}`
745754
console.warn(
746-
`[background] FETCH received error status: ${response.status} for ${fetchInput}`,
755+
`[background] FETCH received error status: ${response.status} for ${validatedUrl}`,
747756
)
748757
}
749758
console.debug(
750-
`[background] FETCH successful for ${fetchInput}, status: ${response.status}`,
759+
`[background] FETCH successful for ${validatedUrl}, status: ${response.status}`,
751760
)
752761
return [responseObject, null]
753762
} catch (error) {
754-
console.error(`[background] FETCH error for ${fetchInput}:`, error)
763+
console.error(`[background] FETCH error for ${validatedUrl}:`, error)
755764
return [null, { message: error.message }]
756765
}
757766
}
@@ -781,6 +790,13 @@ Browser.runtime.onMessage.addListener(async (message, sender) => {
781790
console.warn('[background] Rejecting GET_COOKIE with invalid URL:', cookieUrlInput)
782791
return null
783792
}
793+
if (cookieUrl.protocol !== 'http:' && cookieUrl.protocol !== 'https:') {
794+
console.warn(
795+
'[background] Rejecting GET_COOKIE with disallowed protocol:',
796+
cookieUrl.protocol,
797+
)
798+
return null
799+
}
784800

785801
const cookieName = cookieNameInput.trim()
786802
console.debug('[background] Processing GET_COOKIE message for:', cookieUrl.href)
@@ -878,20 +894,24 @@ try {
878894
const headers = details.requestHeaders
879895
let modified = false
880896
for (let i = 0; i < headers.length; i++) {
881-
if (!headers[i]) {
897+
const header = headers[i]
898+
if (!header || !header.name) {
882899
continue
883900
}
884-
const headerNameLower = headers[i].name?.toLowerCase()
901+
const headerNameLower = header.name.toLowerCase()
885902
if (headerNameLower === 'origin') {
886-
headers[i].value = 'https://www.bing.com'
903+
header.value = 'https://www.bing.com'
887904
modified = true
888905
} else if (headerNameLower === 'referer') {
889-
headers[i].value = 'https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx'
906+
header.value = 'https://www.bing.com/search?q=Bing+AI&showconv=1&FORM=hpcodx'
890907
modified = true
891908
}
892909
}
893910
if (modified) {
894-
console.debug('[background] Modified headers for Bing:', headers)
911+
console.debug(
912+
'[background] Modified headers for Bing (names only):',
913+
headers.map((header) => header?.name).filter(Boolean),
914+
)
895915
}
896916
return { requestHeaders: headers }
897917
} catch (error) {
@@ -914,11 +934,15 @@ try {
914934
(details) => {
915935
const headers = details.requestHeaders
916936
for (let i = 0; i < headers.length; i++) {
917-
const headerNameLower = headers[i]?.name?.toLowerCase()
937+
const header = headers[i]
938+
if (!header || !header.name) {
939+
continue
940+
}
941+
const headerNameLower = header.name.toLowerCase()
918942
if (headerNameLower === 'origin') {
919-
headers[i].value = 'https://claude.ai'
943+
header.value = 'https://claude.ai'
920944
} else if (headerNameLower === 'referer') {
921-
headers[i].value = 'https://claude.ai'
945+
header.value = 'https://claude.ai'
922946
}
923947
}
924948
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)