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
Related
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?
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
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.
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.
I'm trying to execute a function like window.alert for example, from actionscript, when both the html file and the swf file are using the file: protocol.
Does anyone know of someway to do this?
without changing global flash security settings
It looks like it's not possible after reading Controlling access to scripts in a host web page.
For SWF files running locally, calls to these APIs are successful only if the SWF file and the containing web page (if there is one) are in the local-trusted security sandbox. Calls to these methods fail if the content is in the local-with-networking or local-with-filesystem sandbox.
Then this page on local sandboxes basically says that won't work unless the swf is in a "local-trusted sandbox" which a user or installer would need to put it in.
This blog post about the "local-with-filesystem sandbox" says:
First, I think the documentation here is a bit too generous. SWFs loaded from the local file system do face some restrictions. The most relevant restrictions are probably:
The SWF cannot make a call to JavaScript (or vbscript), either through URL or ExternalInterface
The SWF cannot call a HTTP or HTTPS request.
Querystring parameters (ex. Blah.php?querystring=qs-value) are stripped and will not be passed (even for requests to local files)
There is a document "Controlling access to scripts in a host web page" that describes the various ways and restrictions on allowing Flash content to interact with Javascript.
According to the doc, as long as your embed tag contains AllowScriptAccess set to "always" you should be fine regardless of where the page is loaded from.
You need to update the Flash Player settings so that your file path is listed as a "trusted location." You will then be able to use External Interface and other JS communication methods.
Also, you can't pass default JS functions from AS using External Interface (like alert). You need to write custom functions...
ActionScript:
import flash.external.ExternalInterface;
ExternalInterface.call("alertFromFlash", 'hello');
JavaScript:
function alertFromFlash(str) {
alert(str);
}
Alternatively, if you're distributing this to a customer. It can be difficult to explain how to change Flash Player settings, so you can instead run a server from a CD, which bypassing the need for security settings. I've had good luck with the Flying Ant server in the past.