So I'm sure this is probably at least mostly insane, but I was just thinking about AS3/JS interaction and it got me wondering - does anyone know exactly how inefficient calling JS via AS3 is? For example, if you do the following:
import flash.external.ExternalInterface;
ExternalInterface.call("(function() { /* here's a block of code */ })");
Do these calls need to be eval()ed in the end, or are they able to be passed natively?
Regardless: let's be hypothetical for a second and say that you were a heretic and actually stored a good deal of Javascript within a utility SWF (1x1, offscreen, whatever), and had basic DOM events bound to hand those events to AS3 when they fire, which thus uses ExternalInterface to execute the JS immediately - thus the only part of your Javascript that is ever loaded is a little bit to communicate with Flash. A naive person might even say "you could condense numerous JS files into one loaded SWF file, separating them into different MC's or whatever!", but really, that's not the point, and that won't help us any after the page is already loaded.
I've used AS3 and its Socket class in lieu of XHR polling (etc), so I haven't been disappointed with AS3/JS interaction so far. AFAIK AS3 is executed inside the Flash VM which means that it is automatically less efficient than Javascript, correct? Can someone shed some light on how terrible this would be, efficiency-wise?
It is not impossible to deconstruct the AS3 code within a Flash movie. While it would thwart the casual observer, if someone with skills wanted to get at your scripts they would be able to. You would only be throwing a roadblock in their path, not an impassable one, and possibly one that is even less difficult to crack than the code produced by standard JS obfuscators.
As for performance, Flash execution compares well with browser-hosted Javascript interpreters. See http://jacksondunstan.com/articles/232 for one set of comparisons. It is close to the fastest JS for sheer code execution*.
N.B. — And for graphical UI tasks nothing else (i.e., HTML 5) so far has even come close. This may change with IE9's new JS engine and its hardware acceleration, but it is not clear whether Adobe will be able to tap into the same thing at some point.
Related
Good day all.
I would like to count the js functions present on a given page, and then send this number via ajax (the ajax part is the simple part) do you think is it possible to achieve that in javascript? what should be the best way to do it?
thanks in advance.
explanation:
I'm trying to figure out how to counter measure some fraud attempts on some subscription pages, I suspect that some javascript is injected on the page before the user click, so having the number of functions present at the load event, and then the number of those present on the submit event, should lead me in the right direction.
Well, if someone is injecting code to your site, they could just as easily use that code to turn off your code counting functions. You can never trust anything that happens on the client side and must validate everything on the server.
As for the technical side, you'd use a tool like acorn to traverse the syntax tree and find all FunctionDeclaration and FunctionExpressions (and arrows, concise method definitions and methods). That would not find all functions, but it would find all statically created ones.
Once the code started executing it's impossible since it's easily reducable to the halting problem. You don't know if a code will create a function at some point in the future.
We have a mid-size web-app evenly written in MVC.NET/WebAPI and Backbone.Marionette. So, it's fair to say we spend sizable amounts of time at the Chrome and Firebug debug consoles.
Whenever a bug creeps into the code, and we just can't pinpoint exactly were it's coming from, it spawns a familiar nightmare.
Place your breakpoint at some reasonable point (like a function header that looks suspicious)
Refresh the page
Pray that none of the descendants of the function call any jQuery
If indeed we've been pulled into the hole, slowly Step Into and Step Out Of jQuery functions until my desired function is back in scope
Don't forget to breakpoint along the way so that if I Over Step a function that finally pulls me back in, I can start over from that point
Don't panic
This just seems to me like a major speed-bump. Do I really care how jQuery parses a selector? How it maps a function to my variable? Maybe, but in the default case, I certainly don't. I'm just trying to get my variable through the method chain to see what comes out the other end. If something breaks, I probably care about why it broke, but more likely, I'd rather read up on its usage and implement it correctly. I don't care enough to track it through reams of jQuery code.
Now, I understand this is the nature of the browser-loaded-interpretative-language beast that JavaScript is. I'm starting to wonder though, if we've reached a certain maturity level where we can assume that the average developer bug does not require deep inspection of the "standard" (jQuery, Require, REST, you name it) libraries the script was built upon to be resolved.
Or more, precisely, to ASK A QUESTION, is there a debugger that lets me smoothly chart the functionality of my code, with as many callbacks as my code may have, without tangling me into code from "standard" libraries (assuming I tell the debugger what these libraries are)? Is there something out there smart enough to automatically navigate, say, jQuery code, and inject the focus back into my function, if my code gets pulled into the jQuery maze?
And ( please don't post this as Answer ;), but does anyone out there share my frustration, or am I missing something fundamental?
I wonder if it would be possible to drop privileges in Javascript?
function takeAwaySetTimeout()
{
var oldSetTimeout = window.setTimeout;
window.setTimeout = function()
{
console.log("not working anymore!");
};
}
setTimeout("console.log('this works');",0); // "this works!"
takeAwaySetTimeout();
setTimeout("console.log('this works');",0); // "not working anymore!"
unfortunatelly it seesm to me complicated as a simple delete window.setTimeout will bring back the priviledge! So for me this seems indicative to the fact that unfortunatelly Javascript would not provide for taken away privileges.
I am aware that the term privilege is somewhat borrowed.
It is the background to the question that I would conceive any possiblity to workingly remove a [Native Code] function (= that the method .toSource() indicates its an function provided by the javascript engine) from being accessible in some part as a way to secure the code subjected to this limitation (the privileges are dropped) from being less of a safety concern.
clarification
I welcome your request for more clarity, and hope your will respond to it responsibly and de-hold "free" the question!
Please also consider that having received indeed already two helpful answers shows that, there are people who were able to understand the question. Yet sure, if possible (something simply need background....) I also strive for broadening the understanding.
"It's a bit unclear how restricting access to native functions would give more security. Is
this server-side or client-side JavaScript?"
1) it does not very much matter if client or server-side. Maybe a tiny little bit more important seems of course server-side. Because there is likely likely more functionality (i.e. writing to files, access files.....), more then maybe the more limited Javascript inside of Browser would be able to do (but consider new API's power ...and risks!)
2) maybe the choice for window.setTimeout() [Native function] is not perfect (for clarity), as maybe no direct security relationship is obvious. It has been used because it is well known and it is placeholder. see (3)
3) my reasoning is that each functionality that is provided to Javascript code is ambivalent. On the pro side, it enriches "what it can do?" positively and well-meaning code will use it responsible. Yet on the con side a functionality can mean access to things which when abused can cause security related stuff. An example would be that an external Javacript would do a XHR and post information to the server, potentially data that has private data (i.e. customers health state). If then for example it was possible to take away the XHR object better window.XMLHttpRequest the chances for such an abuse would be limited. Plainly "you cannot shoot somebody, not having a gun!". XHR for instance (maybe more clearly than setTimeout) is such a gun. If the "untrusted code" is not really needing XHR, then it is just good sense to take the risk away, by dropping this privilege/functionality.
4) I think (also in the context of the replies) this question has evolved. I think it is clear, yet please post comment if not so. While initially Juhana said:
It's a bit unclear[...]
I understand that it was not totally unclear, and hence now it might have reached enough clarity (please consider the helpful answers) to allow for "deholding"/"freeing the Question". Also if you found the question interesting enough to hold it, then now would be the time to find it interesting enough to upvote it ;)
There are so many ways to get the original function and blacklisting can't work because you'll miss something e.g.
Window.prototype.setTimeout.call(window,'alert(1)');
One solution to this problem is to create a whitelisted sandbox. I've created such a sandbox called MentalJS. This sandbox rewrites all your code with a suffix of $ for example alert(1) becomes alert$(1) this allows you to choose which functions/objects are allowed within the sandbox.
The code is available here:
http://code.google.com/p/mentaljs/
and a demo:
http://businessinfo.co.uk/labs/MentalJS/MentalJS.html
Google uses the Caja compiler in these situations. The unprivileged code is then run either in a server-side sandbox or (in browsers that support ES5) a client-side strict mode sandbox.
So, I am fairly new to JavaScript coding, though not new to coding in general. When writing source code I generally have in mind the environment my code will run in (e.g. a virtual machine of some sort) - and with it the level of code optimization one can expect. (1)
In Java for example, I might write something like this,
Foo foo = FooFactory.getFoo(Bar.someStaticStuff("qux","gak",42);
blub.doSomethingImportantWithAFooObject(foo);
even if the foo object only used at this very location (thus introducing an needless variable declaration). Firstly it is my opinion that the code above is way better readable than the inlined version
blub.doSomethingImportantWithAFooObject(FooFactory.getFoo(Bar.someStaticStuff("qux","gak",42));
and secondly I know that Java compiler code optimization will take care of this anyway, i.e. the actual Java VM code will end up being inlined - so performance wise, there is no diffence between the two. (2)
Now to my actual Question:
What Level of Code Optimization can I expect in JavaScript in general?
I assume this depends on the JavaScript engine - but as my code will end up running in many different browsers lets just assume the worst and look at the worst case. Can I expect a moderate level of code optimization? What are some cases I still have to worry about?
(1) I do realize that finding good/the best algorithms and writing well organized code is more important and has a bigger impact on performance than a bit of code optimization. But that would be a different question.
(2) Now, I realize that the actual difference were there no optimization is small. But that is beside the point. There are easily features which are optimized quite efficiently, I was just kind of too lazy to write one down. Just imagine the above snippet inside a for loop which is called 100'000 times.
Don't expect much on the optimization, there won't be
the tail-recursive optimization,
loop unfolding,
inline function
etc
As javascript on client is not designed to do heavy CPU work, the optimization won't make a huge difference.
There are some guidelines for writing hi-performance javascript code, most are minor and technics, like:
Not use certain functions like eval(), arguments.callee and etc, which will prevent the js engine from generating hi-performance code.
Use native features over hand writing ones, like don't write your own containers, json parser etc.
Use local variable instead of global ones.
Never use for-each loop for array.
Use parseInt() rather than Math.floor.
AND stay away from jQuery.
All these technics are more like experience things, and may have some reasonable explanations behind. So you will have to spend some time search around or try jsPerf to help you decide which approach is better.
When you release the code, use closure compiler to take care of dead-branch and unnecessary-variable things, which will not boost up your performance a lot, but will make your code smaller.
Generally speaking, the final performance is highly depending on how well your code organized, how carefully your algorithm designed rather than how the optimizer performed.
Take your example above (by assuming FooFactory.getFoo() and Bar.someStaticStuff("qux","gak",42) is always returning the same result, and Bar, FooFactory are stateless, that someStaticStuff() and getFoo() won't change anything.)
for (int i = 0; i < 10000000; i++)
blub.doSomethingImportantWithAFooObject(
FooFactory.getFoo(Bar.someStaticStuff("qux","gak",42));
Even the g++ with -O3 flag can't make that code faster, for compiler can't tell if Bar and FooFactory are stateless or not. So these kind of code should be avoided in any language.
You are right, the level of optimization is different from JS VM to VM. But! there is a way of working around that. There are several tools that will optimize/minimize your code for you. One of the most popular ones is by Google. It's called the Closure-Compiler. You can try out the web-version and there is a cmd-line version for build-script etc. Besides that there is not much I would try about optimization, because after all Javascript is sort of fast enough.
In general, I would posit that unless you're playing really dirty with your code (leaving all your vars at global scope, creating a lot of DOM objects, making expensive AJAX calls to non-optimal datasources, etc.), the real trick with optimizing performance will be in managing all the other things you're loading in at run-time.
Loading dozens on dozens of images, or animating huge background images, and pulling in large numbers of scripts and css files can all have much greater impact on performance than even moderately-complex Javascript that is written well.
That said, a quick Google search turns up several sources on Javascript performance optimization:
http://www.developer.nokia.com/Community/Wiki/JavaScript_Performance_Best_Practices
http://www.nczonline.net/blog/2009/02/03/speed-up-your-javascript-part-4/
http://mir.aculo.us/2010/08/17/when-does-javascript-trigger-reflows-and-rendering/
As two of those links point out, the most expensive operations in a browser are reflows (where the browser has to redraw the interface due to DOM manipulation), so that's where you're going to want to be the most cautious in terms of performance. Some of that can be alleviated by being smart about what you're modifying on the fly (for example, it's less expensive to apply a class than modify inline styles ad hoc,) so separating your concerns (style from data) will be really important.
Making only the modifications you have to, in order to get the job done, (ie. rather than doing the "HULK SMASH (DOM)!" method of replacing entire chunks of pages with AJAX calls to screen-scraping remote sources, instead calling for JSON data to update only the minimum number of elements needed) and other common-sense approaches will get you a lot farther than hours of minor tweaking of a for-loop (though, again, common sense will get you pretty far, there, too).
Good luck!
I am trying to figure out any and all ways to prevent CSS modification and DOM modification of specific elements. I understand this might not be completely possible or that a talented developer could get around it, however, I am not so concerned about people potentially getting around it, I just want to stop newbies. In particular those using jQuery. An example would be to delete certain properties on prototype objects etc..
But why you need/want this? If you want to "protect" your code, you can use some JavaScript minifier as Google Closure Compiler or YUI compressor. They will rewrite your script and it will be difficult to read by a human. Nowadays, with tools like Firebug and Grease Monkey it's almost impossible to do what you want.
Don't use CSS or JavaScript :p Depend completely on server side checks etc.
You cannot stop anyone from messing with your javascript or your objects in the page. The way the browser is designed, your code and objects in your page are simply not protected. Everything from bookmarklets to javascript entered at a console to browser plug-ins can mess with your page and code and variables. That is the architecture of a browser.
What you can do is make things a little more difficult such that a little more work is required for some things. Here are a couple of things you could do:
Obfuscating/compressing/minimizing your code will do things like remove comments, remove whitespace, remove some linebreaks, shorten variable names, etc... That does not prevent anyone from modifying things, but does make it more work to understand and figure out.
Putting variables inside closures and not using globals. This makes it harder to directly modify variables from outside of your scripts.
Keep all important data and secrets on your server. Use ajax calls to ask the server to carry out operations using that data or secrets such that the important information is never available in the browser client.
You cannot keep anyone from modifying the DOM. There simply are no protections against that. Your code can check the DOM and refuse to operate if the DOM has been messed with in non-standard ways. But, of course, the code would then be modified to remove that check too.
If you are looking for a jquery specific solution a crude approach will involve altering the jQuery ($) function and replacing it with a custom one that delegates to the original function only if the provided selector does not match the element you want to secure.
(function(){
jQueryOrig = jQuery;
window.jQuery = window.$ = function(){
if (jQueryOrig("#secure").is(arguments[0])) {
throw new Error("Security breach");
} else return jQueryOrig.apply(this, arguments);
}
}());
Of course people using direct DOM manipulation would not be affected.
Also, if you are actually including arbitrary third party code in your production code, you should take a look at Caja ( http://code.google.com/p/google-caja/ ), which limits users to a subset of javascript capabilities. There is a good explanation regarding Caja here : http://due-diligence.typepad.com/blog/2008/04/web-20-investor.html .
This is possible but requires that the JS file to always be loaded from your server. Using observers you can lock CSS properties and using the on DOM remove/add listeners you can lock it to a parent. This will be enough to discourage most modification.
You can actually go a step further and modify core javascript functions making it nearly impossible to modify the DOM without loading the JS file locally or through a proxy. Further security can be added by doing additional domain checks to make sure the JS file is loaded from where it is supposed to be loaded from.
You can make everything in Flash. In Chrome, there's even a bug that prevents users from opening a console if the flash element has focus (not sure how exactly this works, but you can see an example at http://www.twist-cube.com or http://www.gotmilk.com). Even if users do manage to get a console open (which isn't that hard...), still about all you can do is change the shape of the element.