Hi everyone,
I’m currently maintaining a WebExtension for my organization, which is not registered for the moment.
This plugin integrates into a specific web page, and adds content to it, while maintaining a state on an external server, so that XMLHttpRequests are sent to a cross-origin domain.
Configuration: 60.0 (64-bit) on Debian 4.9.65-3+deb9u2 (2018-01-04) x86_64 GNU/Linux
Until Firefox 59 (and still on Google Chrome), everything worked fine: my XHR sent to the server were sent and the cookies saved without any intervention.
However, since 59 and now 60, XHR are sent without any cookies when sent from a content script.
All third party cookies are allowed in my configuration, and the permission is set in the manifest:
{
  "manifest_version": 2,
  "name": "XMLHttpRequest demo",
  "version": "0.0.1",
  "description": "Demo app",
  "permissions": [
    "*://127.0.0.1/*",
    "cookies"
  ],
  "content_scripts": [
    {   
      "matches": ["https://developer.mozilla.org/*"],
      "js": [
        "index.js"
      ],
      "run_at": "document_start"
    }     
  ]     
}
I have read the WebExtension: XMLHttpRequest issues: No cookies or referrer thread and tried it, with no success.
I also tried the Request API
I have set the withCredentials = true for XHR and { credentials: 'include' } for the Request constructor.
Here is the version with the Request API:
;(async function () {
  'use strict'
  const url = 'http://127.0.0.1'
  async function call2 () {
    try {
      const myHeader = new Headers()
      myHeader.append('Content-Type', 'application/json')
      const myRequest = new Request(url, {
        method: 'GET',
        headers: myHeader,
        credentials: 'include',
        cache: 'no-store'
      })
      const response = await fetch(myRequest)
      const json = await response.json()
    } catch (err) {
      console.log(err)
    }
  }
  await call2()
  await call2()
})()
Now the version with the XHR API:
;(async function () {
  'use strict'
  const url = 'http://127.0.0.1'
  function call () {
    return new Promise((resolve, reject) => {
      const req = new XMLHttpRequest()
      req.addEventListener('load', resolve)
      req.addEventListener('error', reject)
      req.addEventListener('abort', reject)
      req.open('GET', url, true)
      req.withCredentials = true
      req.send(null)
    })
  }
  await call()
  await call()
})()
Here, the First request (caught with Burp Suite):
GET / HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: fr-FR,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
content-type: application/json
origin: null
DNT: 1
Connection: close
Ghostery-AntiTracking:  
Pragma: no-cache
Cache-Control: no-cache
Now, the First Response (note that the server is a test one, no cookie is leaked here):
HTTP/1.1 200 OK
X-Powered-By: Express
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=utf-8
Content-Length: 16
ETag: W/"10-66f6f7df"
set-cookie: connect.sid=s%3AHuzyxdcG6OFcjWzw_OujAFh-LzCQe1Zo.MZw3BwBW9QuBoul1vTg1k2QfRj1yD7%2FgrJWmupMHRJQ; Path=/
Date: Mon, 14 May 2018 13:49:36 GMT
Connection: close
{"success":true}
The server defines correctly the cookie in the response.
Now, when the second request is sent, no cookie is sent along with it:
GET / HTTP/1.1
Host: 127.0.0.1
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Firefox/60.0
Accept: */*
Accept-Language: fr-FR,en-US;q=0.7,en;q=0.3
Accept-Encoding: gzip, deflate
content-type: application/json
origin: null
DNT: 1
Connection: close
Ghostery-AntiTracking:  
Pragma: no-cache
Cache-Control: no-cache
My question is the following: What is the right, documented way to make authenticated cross origin requests with WebExtensions ?
What did I miss from the docs ?