On-the-fly javascript interception : solving the sandbox problem.

Use case:

Should your extension require to interact with the current page in a very intimate fashion (and there are opportunities for this...) ,  you may encounter the roadblock of the javascript sandboxing: javascript code and data are confined in different contexts.
Your content script will therefore not be able to access the JS legitimately imported by the page.

Solution:

In order to gain access and interact with the data and code available in the page, the solution is to insert a proxy javascript snippet in the page. But you can't do this by simply adding a script tag. Instead, you will need to:

  • Design a proxy script based on a window event listener
  • Identify the script you need to deal with (using browser debugging tools such as chrome devtools) 
  • Intercept the targetted script at load time and modify it.
  • Send commands thru event messages to your proxy which HAVE access.

Implementation:

1/ Proxy

var proxyCode  = `window.addEventListener('message', 
              function(event){
                 if(event.data.name=='EVENT1') {
                    // do what you want in that case, you're HOME !                 
                   callScriptInPage(event.value);
                 }
              }, false);`;

2/ Interception

function loadSynchronously(url){
  var that_data = null;
  $.ajax({
   url: url,
    success: function(data, textStatus, jqXHR){
      that_data = data;
    },
    async: false
  });
  return that_data;
}
chrome.webRequest.onBeforeRequest.addListener(
    function (details) {
        console.log("instrumenting "+details.url)
        var javascriptCode = loadSynchronously(details.url);
        javascriptCode+= proxyCode;
        return { redirectUrl: "data:text/javascript,"
                             + encodeURIComponent(javascriptCode) };
    },
    { urls: ["https://site.com/script*.js"
               ] },

    ["blocking"]);

3/ Send control events

    window.postMessage({name:"EVENT1",value:"VALUE"},"https://site.com")  

Notes:
- using a wild card in the urls is a good idea to cope with version controlled js files and resist again  future evolutions of the site.
- of course, don't forget to insert "site.com" in your manifest.json permissions for the webRequest interception to work.

Conclusion:

This method has been successfully used in the context of an addon automating property posting on several real-estate websites. The above method has been used to manipulate the google maps objects embbeded in those sites.

Comments

Popular posts from this blog

Extending an extension with a native app.

Filtering console messages in the chrome devtools window

Intercepting file download in chrome