I've got a weird issue with one of my clients , In the client website some code that runs before my code overrides the "window.console" so i can't use it. i tried to create an invisible iframe and use its contentWindow but somehow its also hooked.
So 2 question:
Can i create a new window from its constructor?
Can i extend the "Window.prototype.constructor" so when i will create a new iframe i can protect the properties i want.
No. If the client website runs code before you that overrides window.console, you cannot circumvent that (it appears that the same thing happens when you create an iframe as well), and you cannot recover the console functionality.
Depending on your needs, there may be other ways to achieve what you need. Before window.console was implemented in browsers, developers made their own consoles in HTML and JS, logging messages to an HTML element instead.
Related
With copy("text") in the developer tools console of Chrome and Firefox you can copy a "text" without an user interaction. Is this also possible if the website I've opened also has a function named copy? If yes, how?
If you refer to window overriding:
Unfortunately, once website overrides methods from window object, they are basically gone for good.
There are some workarounds, for instance you could use proxy interceptor like Charles, inject something like <script> window.copy_saved = window.copy; </script> on the very top of the <head> tag and then use copy_saved method with preserved original functionality.
If you refer to accessing functions defined in website's script tags:
It really depends on implementation, if the method is wrapped in structure accessible in window object, then yes, you can find a way to invoke the method. Methods however, can be stored in closure-like objects and thus being inaccessible by outside environment. It usually takes thorough reverse engineering to find a way into minified closures.
I am creating a Firefox extension, and one feature of it that I would like is the ability for the user to inject a script or stylesheet into a specific website, rather like Greasemonkey (except that this will only be for one site). I am adding some functions for the scripts to make use of, which I intended to add from the Content Script into the main (unsafe) window. On the MDN blog, it says that they have made changes to how it should be implemented, so I have based my code on the new implementation as advised in the post, so this is what I have:
var $jq = jQuery.noConflict();//Yes, I am also injecting jQuery at the same time
console.log("created jquery object"); //This works
exportFunction($jq, unsafeWindow, {defineAs: "$jq"});
console.log("This will never be called");
But execution of the script just stops, and in the console it prints Message: TypeError: window is null.
I am testing in Firefox 28 predominantly (I can't seem to get Firefox for Ubuntu to update beyond that right now, and a whole load of issues are forcing me to use Ubuntu in a VM for this), but in Nightly 31a1 (Win7) nothing is ever injected, including a hardcoded style (that works on FF28) so I will have to figure that out at some point. (The PageMod code is here:
var lttWorker = sdk.pageMod.PageMod({
include:["*"],
/*contentScriptFile: [sdk.data.url("jquery.large.js"), sdk.data.url("scripts/bootstrapper.js")],
contentScriptWhen: "ready",*/ //This is commented to test whether it was an issue with the script. It's not.
contentStyle: "#header_bar{background-color:green;}", //This is injected in FF28 but not 31
attachTo: ["existing", "top"],
onAttach: function(){desktopNotifications({title:"attached content worker", text:"The content worker has been successfully attached"})} //This is called in FF28 but not 31
});
lttWorker.on("error", function(){callError("pageWorker failed");}); //This never gets called. Ever.
if anybody is interested)
EDIT: I have now tried it on Firefox 30b and there are still a load of issues, although they seem to be slightly different to both FF28 and 31...
First of all: These new functions are supported in Firefox 30 and later. See #canuckistani answer.
The exportFunction API is way too limited to actually inject something like jQuery with all the complex objects being or containing DOM nodes. That simply won't fly with the structured-clone algorithm that is applied to arguments.
The API is meant as a way for add-ons to communicate with pages bi-directionally, and not to inject complex libraries.
Your best bet is actually creating a script tag using the DOM APIs and putting jQuery there.
I'm doing a couple of things with jQuery in an MTurk HIT, and I'm guessing one of these is the culprit. I have no need to access the surrounding document from the iframe, so if I am, I'd like to know where that's happening and how to stop it!
Otherwise, MTurk may be doing something incorrect (they use the 5-character token & to separate URL arguments in the iframe URL, for example, so they DEFINITELY do incorrect things).
Here are the snippets that might be causing the problem. All of this is from within an iframe that's embedded in the MTurk HIT** (and related) page(s):
I'm embedding my JS in a $(window).load(). As I understand it, I need to use this instead of $(document).ready() because the latter won't wait for my iframe to load. Please correct me if I'm wrong.
I'm also running a RegExp.exec on window.location.href to extract the workerId.
I apologize in advance if this is a duplicate. Indeed - after writing this, SO seems to have a made a good guess at this: Debugging "unsafe javascript attempt to access frame with URL ... ". I'll answer this question if I figure it out before you do.
It'd be great to get a good high-level reference on where to learn about this kind of thing. It doesn't fit naturally into any topic that I know - maybe learn about cross-site scripting so I can avoid it?
** If you don't know, an MTurk HIT is the unit of work for folks doing tasks on MTurk. You can see what they look like pretty quick if you navigate to http://mturk.com and view a HIT.
I've traced the code to the following chunk run within jquery from the inject.js file:
try {
isHiddenIFrame = !isTopWindow && window.frameElement && window.frameElement.style.display === "none";
} catch(e) {}
I had a similar issue running jQuery in MechanicalTurk through Chrome.
The solution for me was to download the jQuery JS files I wanted, then upload them to the secure amazon S3 service.
Then, in my HIT, I called the .js files at their new home at https://s3.amazonaws.com.
Tips on how to make code 'secure' by chrome's standards are here:
http://developer.chrome.com/extensions/contentSecurityPolicy.html
This isn't a direct answer to your question, but our lab has been successful at circumventing (read hack) this problem by asking workers click on a button inside the iframe that opens a separate pop-up window. Within the pop-up window, you're free to use jQuery and any other standard JS resources you want without triggering any of AMT's security alarms. This method has the added benefit of allowing workers to view your task in a full-sized browser window instead of AMT's tiny embedded iframes.
In my code I have a line that dumps the current window (which happens to be a youtube video page):
Firebug.Console.log(myWindow);
It can be seen that window object contains "yt" property, which is another object that can be easily inspected in debugger:
http://i.imgur.com/lHHns.png
Unfortunately, calling
Firebug.Console.log(myWindow.yt);
logs "undefined" - why is that, and how can I access this "yt" property?
Edit: one addidtion that might be important: the code I'm writing is part of a firefox extension, so it's not really running inside a pgae, but in chrome - I'm starting to think that it may be the cause. Can chrome scripts be somehow limited in what they can see/acces as opposed to code in script tags?
For security reasons, Firefox extensions don't access web page objects directly but via a wrapper. This wrapper allows you to use all properties defined by the DOM objects but anything added by page JavaScript will be invisible. You can access the original object:
Firebug.Console.log(XPCNativeWrapper.wrappedJSObject.yt);
However, if you want to interact with the web page from an extension you should consider alternatives where the web page cannot play tricks on you (e.g. running unprivileged code in the content window: myWindow.location.href = "javascript:...").
Firefox and Chrome extensions can't access JavaScript within the page for security reasons.
I have seen confusion like this using asynchronous APIs.
console.log(obj); shows the contents of an object all filled in, but when accessing the object properties in code, they aren't really populated yet due to the call being asynchronous.
Why Chrome and Firefox shows them all filled in is probably just a timing issue as they probably process the console.log() asynchronously as well.
we have developed an Intranet Management Application with Silverlight 4. We have been asked to add the functionality to call a remote desktop tool which is installed on clients using the Intranet SL App. In an earlier version of the tool written in ASP.NET we just added a Javascript function to the aspx page like this:
function RunShellCommand()
{
var launcher = new ActiveXObject("WScript.Shell");
launcher.Run("mstsc.exe");
}
and called it from ASP.NET.
Now it's clear that SL4 is running in a sandbox and that I cant use the AutomationFactory to create a WScript.Shell object (out of browser mode is not an option).
I thought I could circle around the problem by, again, adding the RunShellCommand javascript method in the aspx page where the SL4 control is hosted and call it via
HtmlPage.RegisterScriptableObject("Page", this);
HtmlPage.Window.Invoke("RunShellCommand", "dummydata");
from my ViewModel. When I run the Application the debugger just skips the RegisterScriptableObject method and quits. Nothing happens.
My question is if am doing something wrong or if this just wont work this way.
Is it possible that I cant do a RegisterScriptableObject from a viewmodel?
EDIT: When I explicitly put a try, catch block around the two methods I get an ArgumentException from the first method stating that the current instance has no scriptable members. When I delete the first method and only run the Invoke, I get a browser error stating that the automation server cant create the object. So is there really no way (except OOB mode) to do this?
Yes, the explanation is correct: you should add at least one method with the ScriptableMember attribute in order that you can use the RegisterScriptableObjectmethod. But it is used only for calling C#-methods from JavaScript.
As far as I see, you want to do the opposite: to call JavaScript code from the Silverlight application. Then you need only one line:
HtmlPage.Window.Invoke("RunShellCommand");
The error automation server cant create the object has nothing to do with Silverlight. I'm sure that if you call the JS function directly - the error will remain.
According to the internet, the reason might be not installed Microsoft Windows Script. Or it is because of security restrictions of the browser.