Recently, I was required to develop a chrome extension for some executives. This plugin only targeted a few of our most visited websites. There was a lot of approaches to implement the extension and all our use cases.
One particular challenge was trying to inject scripts from our own CDN into specific web pages. the scripts were required to interact with the page and all variables possible. Since there is a script isolation thing for Chrome Extensions, I felt this was a good challenge to take up in my spare time.
Here is a sample of my content script.
content.js
Even though I had a background script to remove the response Headers I still got the error below.
After reading so many articles I conclude that this could not be achieved without running chrome from the command line, the good thing about running chrome from the command line is that it allows you to specify that chrome should disable certain security features during startup. So I employed the flags below.
In order to make this flag seem like a semi-permanent fix. I created a chrome shortcut on my desktop. right-click on the shortcut and click 'Properties'. and I pasted the long line below into the target field.
The path to the chrome application is
This path may be different in your case but it will be generated automatically for you when you create a shortcut. you can also obtain it by viewing any chrome shortcut created by your computer during installation.
I double-clicked the newly modified shortcut to start chrome, then I reload the extension and reload the web page. As you can see below, we now have a warning and not the usual error observed moments ago, the script gets loaded as expected and also it is executed within the page.
there are still some other issues encountered that will eventually be solved. For example; the recommended architecture supports that only one script should be injected by the extension's content script. This script is called the father-script(composer.js). the father-script is required to detect the page URL and then append other scripts(e.g theme.js) to the page's body tag, or somehow inject more scripts into the context of the page.
whilst it was easy to inject the father script(composer.js) into the webpage using an extension, the father script could not inject other scripts(theme.js) into the page. the father script was only successful when the webpage had loose content-policy headers defined. the below is a typical scenario where content-policy headers were properly defined.
* composer was injected successfully by the extension, but composer could not inject theme.js
This experimentation shows that it is quite easy to inject scripts into a webpage as an extension developer. But there is enough security to make sure that injected scripts can not inject other scripts.
As you might observe the error obtained is not about mixed content but content security error. if this host never declared the content security or defined it as a wild card, then the second-order injection would have worked.
there are suggestions that the extension should inject the other scripts just as the first was loaded. it is all about flexibility. currently, I am exploring the onHeadersReceived event of the chrome extension for this. the official docs said you can only modify the content policy headers if you specify extra-headers as an option. It also advised that this is a resource-intensive approach. but for me, it is worth trying just for experimentation.
Let me know in the comments how you are handling these situations in your dev ops.
feel free to ask for more clarity in the comment, I might just provide a GitHub link if required.
One particular challenge was trying to inject scripts from our own CDN into specific web pages. the scripts were required to interact with the page and all variables possible. Since there is a script isolation thing for Chrome Extensions, I felt this was a good challenge to take up in my spare time.
Here is a sample of my content script.
content.js
document.onreadystatechange = function () {
console.log("document state is:" + document.readyState);
if (document.readyState == "complete") {
let randAntiCache = Math.random().toString().split('.')[1];
let scriptURL4="http://localhost.test/testscript.js?v="+randAntiCache;
let scriptnode4 = document.createElement("script");
scriptnode4.setAttribute("src", scriptURL4);
document.body.appendChild(scriptnode4);
}
}
Even though I had a background script to remove the response Headers I still got the error below.
After reading so many articles I conclude that this could not be achieved without running chrome from the command line, the good thing about running chrome from the command line is that it allows you to specify that chrome should disable certain security features during startup. So I employed the flags below.
--allow-running-insecure-content --disable-web-security --disable-gpu --user-data-dir=%LOCALAPPDATA%\Chromium\Temp
In order to make this flag seem like a semi-permanent fix. I created a chrome shortcut on my desktop. right-click on the shortcut and click 'Properties'. and I pasted the long line below into the target field.
C:\Users\XXX\AppData\Local\Chromium\Application\chrome.exe --allow-running-insecure-content --disable-web-security --disable-gpu --user-data-dir=%LOCALAPPDATA%\Chromium\Temp
The path to the chrome application is
C:\Users\XXX\AppData\Local\Chromium\Application\chrome.exe
I double-clicked the newly modified shortcut to start chrome, then I reload the extension and reload the web page. As you can see below, we now have a warning and not the usual error observed moments ago, the script gets loaded as expected and also it is executed within the page.
there are still some other issues encountered that will eventually be solved. For example; the recommended architecture supports that only one script should be injected by the extension's content script. This script is called the father-script(composer.js). the father-script is required to detect the page URL and then append other scripts(e.g theme.js) to the page's body tag, or somehow inject more scripts into the context of the page.
whilst it was easy to inject the father script(composer.js) into the webpage using an extension, the father script could not inject other scripts(theme.js) into the page. the father script was only successful when the webpage had loose content-policy headers defined. the below is a typical scenario where content-policy headers were properly defined.
* composer was injected successfully by the extension, but composer could not inject theme.js
As you might observe the error obtained is not about mixed content but content security error. if this host never declared the content security or defined it as a wild card, then the second-order injection would have worked.
there are suggestions that the extension should inject the other scripts just as the first was loaded. it is all about flexibility. currently, I am exploring the onHeadersReceived event of the chrome extension for this. the official docs said you can only modify the content policy headers if you specify extra-headers as an option. It also advised that this is a resource-intensive approach. but for me, it is worth trying just for experimentation.
Let me know in the comments how you are handling these situations in your dev ops.
feel free to ask for more clarity in the comment, I might just provide a GitHub link if required.
Comments
Post a Comment