Eragon27
Eragon27

Reputation: 11

Extract cookie from chrome.webRequest.onBeforeSendHeaders

I'm working on a Firefox add-on to intercept HTTP requests and extract the cookie. I was able to extract 'User-agent' from the header but was unable to extract the cookie. The code I used is below.

chrome.webRequest.onBeforeSendHeaders.addListener(function(details){
  var headers = details.requestHeaders,
  blockingResponse = {};

  for( var i = 0, l = headers.length; i < l; ++i ) {
    window.alert("Checking headers");
    if( headers[i].name == 'Cookie' ) {
       headers[i].value = 'twid=notsecret';
       window.alert("Cookie Changed");
       console.log(headers[i].value);
       break;
    }
  }

  blockingResponse.requestHeaders = headers;
  return blockingResponse;
},
{urls: [ "<all_urls>" ]},['requestHeaders','blocking']);

Why is this not working and are there alternative methods?

Upvotes: 1

Views: 3423

Answers (2)

丶 Limeー来夢 丶
丶 Limeー来夢 丶

Reputation: 947

You may need to have extraHeaders on the options if you use the recent versions of Chrome.

Starting from Chrome 72, the following request headers are not provided and cannot be modified or removed without specifying 'extraHeaders' in opt_extraInfoSpec

chrome.webRequest - Chrome Developers

So, a quick example of removing Cookies would be something similar to:

/**
 * removes cookies 
 */
chrome.webRequest.onBeforeSendHeaders.addListener(function (details) {
  var blockingResponse = {};
  details.requestHeaders.find(a => a.name == "Cookie").value = ``
  blockingResponse.requestHeaders = details.requestHeaders;
  return blockingResponse;
}, { urls: ["<all_urls>"], }, ['requestHeaders', 'extraHeaders', 'blocking', ]);

Upvotes: 1

Makyen
Makyen

Reputation: 33296

You are, probably, testing in a version Firefox earlier than version 49.0a:
The most likely reason this is not working for you is that you are testing in a Firefox version earlier than version 49.0a (which is currently in beta). If so, your code will throw an error when you try to use window.alert(). By Firefox version 49.0a, alert() no longer throws an error, but opens the Browser Console and prints the following line (in addition to the text you were attempting to show in the alert()):

alert() is not supported in background windows; please use console.log instead.

In Firefox versions prior to 49.0a you will see the following errors in the Browser Console when you try to alert():

NS_ERROR_NOT_AVAILABLE: Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMWindowUtils.isParentWindowMainWidgetVisible]                   nsPrompter.js:346
uncaught exception: unknown (can't convert to string)                                                                                                              (unknown)

In your instance, using an alert() in your webRequest listener, the error message would have been a bit different:

NS_ERROR_NOT_AVAILABLE: Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMWindowUtils.isParentWindowMainWidgetVisible]                                                                                                                                                                 nsPrompter.js:346
[Exception... "Component returned failure code: 0x80040111 (NS_ERROR_NOT_AVAILABLE) [nsIDOMWindowUtils.isParentWindowMainWidgetVisible]"  nsresult: "0x80040111 (NS_ERROR_NOT_AVAILABLE)"  location: "JS frame :: resource://gre/components/nsPrompter.js :: openModalWindow :: line 346"  data: no]             (unknown)

Your code works as written:
Other than that, your code works as written in the question. However, when you are outputting the new cookie value via console.log() does not verify that the request headers actually got changed. In order to do that, you will need to add an additional listener on the next event to fire in the chain: webRequest.onSendHeaders.

Here is some modified code that verifies the cookie header has actually been changed. It is tested and verified to be working in FF48.0.2+:

manifest.json:

{
    "description": "Demonstrate changing the cookie of a WebRequest",
    "manifest_version": 2,
    "name": "change-webrequest-cookie-demo",
    "version": "0.1",

    "permissions": [
        "webRequest",
        "webRequestBlocking",
        "<all_urls>" //Required for Google Chrome. Not, currently, needed for Firefox.
    ],

    "background": {
        "scripts": ["background.js"]
    }
}

background.json:

/*Demonstrate changing the cookie of a WebRequet */
// For testing, open the Browser Console
try{
    //Alert is not supported in Firefox. In in FF49.0+, forces the Browser Console open.
    alert('Open the Browser Console.');
}catch(e){
    //alert throws an error in Firefox versions earlier than 49.0
    console.log('Alert threw an error. Probably, the version of Firefox is less than 49.');
}

chrome.webRequest.onBeforeSendHeaders.addListener(function(details){
  var blockingResponse = {};
  //console.log("Checking headers");
  details.requestHeaders.some(function(header){
      if( header.name == 'Cookie' ) {
          console.log("Original Cookie value:" + header.value);
          header.value = 'twid=notsecret';
          console.log("Cookie Changed");
          return true;
      }
      return false;
  });
  blockingResponse.requestHeaders = details.requestHeaders;
  return blockingResponse;
}, {urls: [ "<all_urls>" ]},['requestHeaders','blocking']);

chrome.webRequest.onSendHeaders.addListener(function(details){
  details.requestHeaders.some(function(header){
      if( header.name == 'Cookie' ) {
          console.log("New Cookie value:" + header.value);
          return true;
      }
      return false;
  });
}, {urls: [ "<all_urls>" ]},['requestHeaders']);

General notes on testing and development of WebExtensions in Firefox

Use Firefox Developer Edition, or Firefox Nightly:
The WebExtensions API is very much still in development. What is working improves with each version of Firefox. For now, you are probably best off developing and testing your WebExtension add-on with Firefox Developer Edition, or Firefox Nightly. You should also make careful note of what version of Firefox is required for the functionality you desire to use. This information is contained in the "Browser compatibility" section of the MDN documentation pages.

Use the Browser Console:
You should use the Browser Console to view console.log() output from you WebExtension background scripts. If you had been viewing the Browser Console, you would have seen the error messages. You still would have had to figure out what the error messages mean. But, you would have at least had something more to search about and include in your question.

Upvotes: 2

Related Questions