Is it a good use case for eval in Chrome extension? - javascript

I am developing a Chrome extension that absolutely always needs to run with the newest code.
Now, this is a problem that I am not quite sure how to solve while not going for eval() alike functionality.
I designed it to fetch the newest script from server over HTTPS, then execute it using new Function()
It's absolutely most important to have extension run using newest code for every user and updates managed by Google don't solve that problem cause they are usually delayed or require user to update it manually.
CSP only allows for scripts executed from domain specified by me, but I am also using unsafe-eval although I can encode these scripts using hash for more security.
Scripts require access to page DOM and chrome.* API. I can't just specify them as script src in popup, because that's not the point.
Are there better solutions to this problem?

Related

How do you properly handle caching static web content?

Browsers cache static files. It's what they're designed to do. 99% of the time, that's a good thing. Until we as developers update that static content.
If a developer updates a javascript file, but a user's browser pulls the cached version of it, then:
Best case, it'll be missing some new functionality until the browser decides to update its cache
Worse case, if you also updated the html page to call a javascript function that didn't exist in the older version of the javascript file that the browser cached, your page breaks
As developers, we know to hit Ctrl+Shift+R, or Ctrl+F5, or open dev console, disable cache on the Network tab, and reload. But users don't know that.
What is the best practice to handle updates to static content?
Is it to make sure that when you add new functions to a .js file, you push out the update to production a few hours/days before you update the html to call that function in <script> tags, allowing browsers to updated their cache over that time?
Is it to not call javascript functions from HTML within <script> tags at all?
Is there a way to somehow force browsers to expire cache on a specific static file when you update it?
Something else?
Obviously disabling all caching on your site is possible, but not a realistic solution.
PS. I'm not using any kind of frontend framework - just raw javascript/jquery. If the situation is different with frontend frameworks, I'd love to heard about that too at a high level
If I understand correctly, you want the JavaScript file to be updated for the user when you update. you should use service work API to create a cache version for specific files or use the Google workbox library. click here. for service worker API click here
Some years ago location.reload(true) allowed bypassing the cache like CTRL / Command+Shift+R does. Only Firefox continues to support this feature by now, but the hard reload using javascript is no longer supported on chromium based browsers. (spec doesn't describe this feature (anymore))
This change was also discussed on this issue on github/Microsoft/TypeScript and several other places on the web.
jQuery uses a simple workaround to be compatible with almost everything. If you load something with jQuerys jQuery.ajax({ url, cache: false }), it appends a _=TIMESTAMP parameter to the url, which has a similar effect but may bloat the cache.
You can make use of the Entity tag header (ETag). Entity tags are similar to fingerprints and if the resource at a given URL changes, a new Etag value must be generated by the server, which is a similar behavior to the Last-Modified header. (caniuse:etag)
Entity tags in: Apache, IIS, nginx (nginx docs), nodejs
It is also possible to clear the sites cache with a Clear-Site-Data: "cache" header. (mdn, caniuse:clear-site-data)

Check if user has a third party Chrome extension installed

I am currently trying to detect if a user has a certain Chrome extension installed. The Chrome extension is not my own and I do not have the source code to it. I have tried methods in numerous posts but they all fail. What I've tried and why it failed is detailed below.
This results in 'cannot read property connect of undefined' when executed:
var myPort=chrome.extension.connect('idldbjenlmipmpigmfamdlfifkkeaplc', some_object_to_send_on_connect);
Trying to load a resource of the extension as follows to test if it's there but going to this URL in browser results in 'your file was not found' Chrome error page (note that I found this path by going to C:\Users\\AppData\Local\Google\Chrome\User Data\Default\Extensions\idldbjenlmipmpigmfamdlfifkkeaplc\1.0.0.1_0\ on my Windows local machine):
chrome-extension://idldbjenlmipmpigmfamdlfifkkeaplc/1.0.0.1_0/icon_16.png
Using Chrome management but this results in console error 'cannot read property get of undefined' when executed
chrome.management.get("idldbjenlmipmpigmfamdlfifkkeaplc", function(a){console.log(a);});
And most other answers I've come across seem to involve the extension being written by the same person who is trying to check for it.
Assuming you need it from a website
connect/message method implies that the extension specifically listed your website in the list of origins it expects connection from. This is unlikely unless you wrote this extension yourself, as this cannot be a wildcard domain.
Referring to files within the extension from web context will return 404 simulate a network error unless the extension declared them as web-accessible. This used to work before 2012, but Google closed that as a fingerprinting method - now extensions have to explicitly list resources that can be accessed. The extension you specifically mention doesn't list any files as web-accessible, so this route is closed as well.
chrome.management is an extension API; websites cannot use it at all.
Lastly, if an extension has a content script that somehow modifies the DOM of your webpage, you may detect those changes. But it's not very reliable, as content scripts can change their logic. Again, in your specific case the extension listens to a DOM event, but does not anyhow make clear the event is received - so this route is closed.
Note that, in general, you cannot determine that content script code runs alongside yours, as it runs in an isolated context.
All in all, there is no magic solution to that problem. The extension has to cooperate to be discoverable, and you cannot bypass that.
Assuming you need it from another extension
Origins whitelisted for connect/message method default to all extensions; however, for this to work the target extension needs to listen to onConnectExternal or onMessageExternal event, which is not common.
Web-accessible resources have the same restrictions for access from other extensions, so the situation is not better.
Observing a page for changes with your own content script is possible, but again there may be no observable ones and you cannot rely on those changes being always the same.
Similar to extension-webpage interaction, content scripts from different extensions run in isolated context, so it's not possible to directly "catch"code being run.
chrome.management API from an extension is the only surefire way to detect a 3rd party extension being installed, but note that it requires "management" permission with its scary warnings.

How to load fb all.js script on a Firefox addon

I am trying to load asynchronously the connect.facebook.net/en_US/all.js script , see here
The problem is that fbAsyncInit is never get called...
This is because 'window' in a content script is not the real window, but a proxy. I can get your code working by replacing window with 'unsafeWindow':
https://builder.addons.mozilla.org/package/157253/latest/
Note that this introduces a possible security issue - in particular you should not trust any data that comes form unsafeWindow or anything attached to it. This is a hack that can be used to get things working in cases where the the proxy will not, but could be used to allow web pages to execute arbitrary code with the privileges of the browser.

How to auto-update javascript in chrome extensions

I have a chrome extension which have a server-side javascript and I need this js to be reloaded every [1] hour on the client side. What´s the best way to do it?
Method 1
Bump your extension version every couple of hours. Chrome will automatically update the extension: http://code.google.com/chrome/extensions/autoupdate.html.
Method 2, distinguishing cases:
JSON: When the "server-side JS" only contains data, this is the best solution. Use setInterval in the background page to regularly update the variables. Do not forget to set the permissions in manifest.json, to enable cross-origin XHR.
The response can be parsed with JSON.parse.
Script: Another option is to dynamically inject <script> tags in the background page.
Warning: Loading and executing external scripts in the background page poses a potential security hole in the extension.
When the network connection or your server is compromised, an evil third party can execute arbitrary code with your extension's privileges!
Ask your question in more clear way. As far as i understand you want to update the js-code on client-side every hour. If so, you can't do this in chrome extensions.

Inject dynamic script in Firefox extension

I'm doing an extension now and i have one part of script which is static (will never change) and another part which is loaded from the website. And, i'm seeing 2 ways:
To load it with XMLHttpRequest and inject into web page
To put it as a <script src="example.com/myscript.js"></script> and have it load it itself
But, the second way probably won't have access to my extension API (to functions defined in extension files, i.e. in chrome://myext/script.js)
And, the first way will probably be unsecure because i will have to eval the code in a gBrowser.contentWindow.wrappedJSObject object which is a Window object for the loaded page
Any ideas?
Are you saying that you want the dynamic script to have chrome privileges? If so, why not load it using XMLHttpRequest, save it to disk and then import it as a JavaScript Module (https://developer.mozilla.org/en/JavaScript_code_modules/Using). Obviously there are security considerations since you are giving a script from the web pretty much unlimited privileged, but if you control the script's source then you are presumably okay. If you are really worried you can use HTTPS to download the script, which will protect against someone intercepting the traffic.
If you want the code to run with content privileges but have access to functions in your chrome JavaScript, then maybe you want to expose the chrome functions to content as described in this article: http://weblogs.mozillazine.org/weirdal/archives/017188.html

Categories

Resources