1075

In Chrome extensions, can you force some javascript to be injected before everything?

Question:

I have a Chrome extension (source provided below) that is getting caught with a race condition. I need some injected JavaScript to run before all other JavaScript on a web page.

The source code of a simple example of what I'm trying to do is here: <a href="https://github.com/nddipiazza/oogi" rel="nofollow">https://github.com/nddipiazza/oogi</a>

It is attempting to add a namespace to all cookie names that will actually be persisted as cookies, but at the same time remove those namespaces from the cookies that are in use.

So let's say normally without the extension you would have 2 cookies that are saved after accessing a site:

JSESSIONID lastVisit

This extension would save them as:

oogi$JSESSIONID oogi$lastVisit

There are basically two major parts to the extension.

<ul><li>

<a href="https://github.com/nddipiazza/oogi/blob/master/background.js" rel="nofollow">https://github.com/nddipiazza/oogi/blob/master/background.js</a> This intercepts the incoming and outgoing http headers so that it can properly add the namespace to the incoming cookies and remove the ones from the outgoing. This way the namespace of the cookie is purely local to us.

</li> <li>

<a href="https://github.com/nddipiazza/oogi/blob/master/inject.js" rel="nofollow">https://github.com/nddipiazza/oogi/blob/master/inject.js</a> This intercepts JavaScript cookie get and set operations for the same reason as we do it for the headers.

</li> </ul>

The problem here is that in order for this to work, I need the javascript cookie header intercepts in inject.js to absolutely always be loaded before any other javascript. But it doesn't.

Example: Cookies in inline javascript such as:

<body> <H2>Cookies from Inline JavaScript</H2> <script> console.log("Inline javascript is executed."); document.write(listCookies()); </script> </body>

Will already load prior to the inject cookie interceptor being loaded. You can tell from the console log will read in this order:

Inline javascript is executed. cookie get/set injector completed

Is there a way to fix this inject race condition? I want to allow a chrome extension to force a javascript to be run prior to doing <em>any</em> javascript on a page.

Answer1:

Thanks to the comments on this ticket, the solution in my case was Method 2 from this answer: <a href="https://stackoverflow.com/a/9517879" rel="nofollow">https://stackoverflow.com/a/9517879</a>

Special thanks to <a href="https://stackoverflow.com/users/3959875/woxxom" rel="nofollow">https://stackoverflow.com/users/3959875/woxxom</a>

Here is a link to the finished solution:

<a href="https://github.com/nddipiazza/oogi/commit/64e1ef8dc3abfb32fec2db5fb67891a29cfe12ea" rel="nofollow">https://github.com/nddipiazza/oogi/commit/64e1ef8dc3abfb32fec2db5fb67891a29cfe12ea</a>

The important part of the code that makes the difference is here

var actualCode = `var cookieGetter = document.__lookupGetter__("cookie").bind(document); var cookieSetter = document.__lookupSetter__("cookie").bind(document); var getPrefix = function() { return "oogi$" }; var processCookieStr = function(cookiesStr) { var prefix = getPrefix(); var cookieStrList = cookiesStr.split('; '); var newStrList = []; cookieStrList.forEach(function(cookieStr){ if (cookieStr.indexOf(prefix)==0) { newStrList.push(cookieStr.substring(prefix.length, cookieStr.length)); } }); return newStrList.join("; "); }; var processSetCookieStr = function(str) { console.log("Processing set cookie string " + str); return getPrefix()+str; }; Object.defineProperty(document, 'cookie', { get: function() { var storedCookieStr = cookieGetter(); console.log("Intercepted a cookie get " + storedCookieStr + " , and returning processed cookie string " + processCookieStr(storedCookieStr)); return processCookieStr(storedCookieStr); }, set: function(cookieString) { var newValue = processSetCookieStr(cookieString); console.log("Intercepted a cookie set " + newValue) return cookieSetter(newValue); } }); console.log("cookie get/set injector completed"); `; var script = document.createElement('script'); script.textContent = actualCode; (document.head||document.documentElement).appendChild(script); script.remove();

Recommend

  • Conditional selection of data in a pandas DataFrame
  • A Generlized XML serializer but not working on JObject
  • F# adding polynomials recursively
  • Arrays.asList also for maps? [duplicate]
  • Changing FireFox Push Message Provider
  • Can't subscribe to Push notification
  • How to use Sanitize on HTML Entity
  • Create and use temp table in nested queries
  • Firebase Cloud Messaging: how to send data message to all users? [duplicate]
  • Processing dynamic MP3 URL
  • Git objects SHA-1 are file contents or file names?
  • password_hash() not working [closed]
  • How to hide 'Add To Cart' for variable products, but keep product variations visible
  • Javapackager tool from command-line on OSX?
  • Migrating MOSS 2007 from SQL 2000 to SQL 2005 [closed]
  • Newtonsoft.json serializing and deserializing base/inheirited where classes are from shared projects
  • Detect when MathJax has finished loading in UIWebView
  • Finding all XML nodes between each two processing instructions
  • Sorting Custom Listview Items Using Spinner Android
  • Validating a Firebase Key [duplicate]
  • VS2010: Ctrl-PgUp / -PgDown like in browsers
  • Use 2D Text into 3D scenes in JavaFX results in blurry texts
  • Implementation of timeout in LDAP
  • view details for exception in vs 2017
  • How to select multiple items from a List view - JavaFX 8
  • Ruby on Rails: Get mediaplayer information (iTunes, TRAKTOR, Cog; current song + playlist)
  • Annotate objects in a queryset with next and previous object ids
  • PHPMailer return to AJAX
  • How to split wav file into two or more parts using c#
  • Content-Type alternative in MQTT
  • Android: Unable to detect vertical plane
  • How to integrate angular2-material (alpha 8.2) with angular2-Quickstart app
  • Debug `Unexpected end of JSON input Error` on content script
  • How to encrypt Connectionstring written in web.config from codebehind?
  • Apple Mach-O Linker error (“duplicate symbol”)
  • Excel VBA : conditional formatting of sheet1 cells from sheet2 values in excel 2007
  • XEP-0166: Jingle protocol implementation for voice/video chat in iOS
  • Call Microservice from another Microservice within Docker
  • Angular FormGroup won't update it's value immediately after patchValue or setValue
  • How to use FirstOrDefault inside Include