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

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.

Related

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

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?

Share a variable between multiple userscripts [duplicate]

I have two scripts. I put them in the same namespace (the #namespace field).
I'd like them to interactive with another.
Specifically I want script A to set RunByDefault to 123. Have script B check if RunByDefault==123 or not and then have script A using a timeout or anything to call a function in script B.
How do I do this? I'd hate to merge the scripts.
The scripts cannot directly interact with each other and // #namespace is just to resolve script name conflicts. (That is, you can have 2 different scripts named "Link Remover", only if they have different namespaces.)
Separate scripts can swap information using:
Cookies -- works same-domain only
localStorage -- works same-domain only
Sending and receiving values via AJAX to a server that you control -- works cross-domain.
That's it.
Different running instances, of the same script, can swap information using GM_setValue() and GM_getValue(). This technique has the advantage of being cross-domain, easy, and invisible to the target web page(s).
See this working example of cross-tab communication in Tampermonkey.
On Chrome, and only Chrome, you might be able to use the non-standard FileSystem API to store data on a local file. But this would probably require the user to click for every transaction -- if it worked at all.
Another option is to write an extension (add-on) to act as a helper and do the file IO. You would interact with it via postMessage, usually.
In practice, I've never encountered a situation were it wasn't easier and cleaner to just merge any scripts that really need to share data.
Also, scripts cannot share code, but they can inject JS into the target page and both access that.
Finally, AFAICT, scripts always run sequentially, not in parallel. But you can control the execution order from the Manage User Scripts panel

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 check if Chrome extension has fully installed

Using Chrome Web Store inline installation ( https://developers.google.com/chrome/web-store/docs/inline_installation ) it is possible to specify a callback for chrome.webstore.install() that will be executed when the extension is successfully installed.
Through some very tedious debugging I've learned that extensions are not neccessarily 100% installed when the callback is executed - maybe the background hasn't been loaded or content scripts aren't yet available.
In my particular case the problem presents itself in this way:
User clicks install button with chrome.webstore.install() bound to onclick event.
Success callback injects an iFrame.
Content script is defined for the iFrame and injected to do some finishing work
Content script returns with a completed installation dialog.
Step 3 is the problem. Some times the iFrame will be injected before content script is fully loaded and thus no script will be injected (content scripts are only injected inside newly created iFrames, not iFrames already existing when the extension is installed/enabled).
I know there are possible workarounds such as having the extension itself inject the iFrame or a simple setTimeout(), but for the sake of helping others I think it's worth asking the question:
How can I be certain that the extension is 100% installed, when the chrome.webstore.install() callback doesn't ensure it?
Using the famous <img> load method described in Checking if user has a certain extension installed doesn't work reliably (for those thinking that'd be a solution).
This is the way to do it :
http://code.google.com/chrome/extensions/extension.html#global-events
As mentioned in the last link below , you should be able to do :
var myPort=chrome.extension.connect('yourextensionid_qwerqweroijwefoijwef', some_object_to_send_on_connect);
You can also check Checking if an item is already installed section in the next link :
https://developers.google.com/chrome/web-store/docs/inline_installation
or you can follow what have been done in this post:
Check whether user has a Chrome extension installed
I also saw solutions talking about background page and localstorage:
http://developer.chrome.com/extensions/background_pages.html
Chrome extension post-install hook/API function: does it exist?
You sure your content script's work needs to be done from the same page where the user installed the extension? If not, simply have your extension call chrome.tabs.update or chrome.tabs.create (two of the few tabs methods that don't require the tabs permission) to open a page where your content script can be injected.
Otherwise, your extension can use programmatic injection to inject a content script which can communicate with your page. You can use chrome.tabs.query to make sure you're injecting into the correct tab.

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