diff --git a/src/background/messages/makeRequest.ts b/src/background/messages/makeRequest.ts index 14e0b77..2e1fd9a 100644 --- a/src/background/messages/makeRequest.ts +++ b/src/background/messages/makeRequest.ts @@ -5,7 +5,7 @@ import type { BaseResponse } from '~types/response'; import { removeDynamicRules, setDynamicRules } from '~utils/declarativeNetRequest'; import { isFirefox } from '~utils/extension'; import { makeFullUrl } from '~utils/fetcher'; -import { assertDomainWhitelist } from '~utils/storage'; +import { assertDomainWhitelist, canAccessCookies } from '~utils/storage'; const MAKE_REQUEST_DYNAMIC_RULE = 23498; @@ -60,6 +60,12 @@ const handler: PlasmoMessaging.MessageHandler> = async (r ruleId: MAKE_REQUEST_DYNAMIC_RULE, targetDomains: [new URL(url).hostname], requestHeaders: req.body.headers, + // set Access-Control-Allow-Credentials if the reqested host has access to cookies + responseHeaders: { + ...(canAccessCookies(new URL(url).hostname) && { + 'Access-Control-Allow-Credentials': 'true', + }), + }, }); const response = await fetch(url, { @@ -84,7 +90,10 @@ const handler: PlasmoMessaging.MessageHandler> = async (r statusCode: response.status, headers: { ...Object.fromEntries(response.headers.entries()), - 'Set-Cookie': cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join(', '), + // include cookies if allowed for the reqested host + ...(canAccessCookies(new URL(url).hostname) && { + 'Set-Cookie': cookies.map((cookie) => `${cookie.name}=${cookie.value}`).join(', '), + }), }, body, finalUrl: response.url, diff --git a/src/utils/declarativeNetRequest.ts b/src/utils/declarativeNetRequest.ts index 7b5e710..b58bd0a 100644 --- a/src/utils/declarativeNetRequest.ts +++ b/src/utils/declarativeNetRequest.ts @@ -1,4 +1,5 @@ import { isChrome } from './extension'; +import { modifiableResponseHeaders } from './storage'; interface DynamicRule { ruleId: number; @@ -20,6 +21,17 @@ const mapHeadersToDeclarativeNetRequestHeaders = ( }; export const setDynamicRules = async (body: DynamicRule) => { + // restrict what response headers can be modified + body.responseHeaders = Object.keys(body.responseHeaders ?? {}) + .filter((key) => modifiableResponseHeaders.includes(key.toLowerCase())) + .reduce( + (obj, key) => { + obj[key] = (body.responseHeaders ?? {})[key]; + return obj; + }, + {} as Record, + ); + if (isChrome()) { await chrome.declarativeNetRequest.updateDynamicRules({ removeRuleIds: [body.ruleId], @@ -56,11 +68,6 @@ export const setDynamicRules = async (body: DynamicRule) => { operation: chrome.declarativeNetRequest.HeaderOperation.SET, value: '*', }, - { - header: 'Access-Control-Allow-Credentials', - operation: chrome.declarativeNetRequest.HeaderOperation.SET, - value: 'true', - }, ...mapHeadersToDeclarativeNetRequestHeaders( body.responseHeaders ?? {}, chrome.declarativeNetRequest.HeaderOperation.SET, @@ -104,11 +111,6 @@ export const setDynamicRules = async (body: DynamicRule) => { operation: 'set', value: '*', }, - { - header: 'Access-Control-Allow-Credentials', - operation: 'set', - value: 'true', - }, ...mapHeadersToDeclarativeNetRequestHeaders(body.responseHeaders ?? {}, 'set'), ], },