google-chromecookiesiframegoogle-chrome-extensiongoogle-account

Login to accounts.google.com with an iframe


In my managed enterprise app I have an embedded (iframe) web page (I don't own it) which uses accounts.google.com to do authentication. I'm also using a chrome manifest v3 extension to remove X-Frame-Options header and to set cookies which come from iframes (to solve SameSite=Lax set-cookie).

accounts.google.com loads correctly, all cookies are also seem to be set and eventually sent correctly, but accounts.google.com still says that I have cookies disabled.

What am I missing? Why does accounts.google.com still says I have cookies disabled? Even though they are correctly set (I have compared cookies in devtools embeded vs not-embeded accounts.google.com).

background.ts

...

chrome.webRequest.onHeadersReceived.addListener(
  details => {
    const cookiesHeaders = (
      details.responseHeaders?.filter(h => h.name.toLowerCase() === 'set-cookie') || []
    )
      .map(h => h.value)
      .filter((value): value is string => !!value);
    const cookies = parseCookiesHeaders(cookiesHeaders);

...

chrome.cookies.set({
      url: url,
      name: cookie.name,
      value: cookie.value,
      path: cookie.path,
      domain: cookie.domain,
      secure: true,
      httpOnly: cookie.httpOnly,
      expirationDate: cookie.expires ? cookie.expires.getTime() / 1000 : undefined,
      sameSite: 'no_restriction',
}),

...

chrome.declarativeNetRequest.updateSessionRules(
...

responseHeaders: [
          {
            header: 'X-Frame-Options',
            operation: chrome.declarativeNetRequest.HeaderOperation.REMOVE,
          },
          {
            header: 'Frame-Options',
            operation: chrome.declarativeNetRequest.HeaderOperation.REMOVE,
          },
...

Solution

  • solution based on @wOxxOm comments:

    background.ts

    chrome.scripting.registerContentScripts([
      {
        allFrames: true,
        id: 'some-id',
        js: ['inject-same-site-none-cookies.js'],
        matches: ['<all_urls>'],
        runAt: 'document_start',
        world: 'MAIN',
      },
    ]);
    

    inject-same-site-none-cookies.ts

    if (window !== top) {
      const obj = Document.prototype,
        k = 'cookie',
        pd = Object.getOwnPropertyDescriptor(obj, k);
      Object.defineProperty(obj, k, {
        ...pd,
        set(v) {
          return pd.set.call(this, v + '; SameSite=None; Secure');
        },
      });
    }