privilege dropping possible in Javascript? - javascript

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.

Related

How do you know which parameters to set for a javascript function?

Coming from Java, Javascript can be really frustrating.
I'm hoping someone can put this into simple terms for me.
I'm struggling to understand how Javascript programmers know which parameters to pass for a method they're calling - especially when that method is being called as a callback (which in my eyes seems like an added level of complexity).
For example, take the function addEventListener. In this function, a typical use looks like
myDOMItem.addEventListener("click", function(e){...}, false);
In the documentation for this function (hyperlinked to name above) I don't see any mention of this option. Whereas in Java you can easily know if your parameters match the type especially with a good IDE, in Javascript it seems like a huge guessing game or requires serious in-depth knowledge of each function.
How do Javascript programmers do it?
The documentation you linked to does show the form in your example:
target.addEventListener(type, listener[, useCapture]);
The type parameter is the string "click", listener is the function object, and useCapture is false.
We either remember things, or get a good IDE that actually has decent support. Everyone has their favorite, so I won't presume to say that there is a "best" IDE. In my humble opinion, Webstorm is one of the best.
In the Mozilla documentation is clearly stated that the function takes four arguments:
string (type)
function/implementer of EventListener (listener)
boolean (useCapture).
boolean (wantsUntrusted). Available only for Mozilla/Gecko browsers.
As you can see from the signature, last two parameters are optional and therefore wrapped in brackets:
target.addEventListener(type, listener[, useCapture, wantsUntrusted ]);
To effectively code in JavaScript, you need to organize development environment just like for Java. Java world provides almost endless number of tools for different tasks (UI development, server-side development etc.). The same situation with JavaScript. I would like to avoid ads for IDEs/Editors. Therefore I advise you to use search to find the right tools for your JavaScript-related dev stack.
P.S. Personal opinion. I also came to JavaScript from Java. From my experience, the main problem for Java developers is not the lack of tools but the lack of strict code structure. Since Java gives powerful OOP experience, probably it will be more easily for you to start working with JavaScript in OOP terms. Good development stack for OOP-like JavaScript is provided by the open source project Google Closure Tools.

How can I prove that my JavaScript files are in the scope of a specific JS or ECMA version?

Let's say you would get a bunch of .js files and now it is your job to sort them into groups like:
requires at least JavaScript 1.85
requires at least E4X (ECMAScript 4 EX)
requires at least ECMAScript 5
or something like this.
I am interested in any solution, but especially in those which work using JavaScript or PHP. This is used for creation of automated specifications, but it shouldn't matter - this is a nice task which should be easy to solve - however, I have no idea how and it is not easy for me. So, if this is easy to you, please share any hints.
I would expect something like this - http://kangax.github.com/es5-compat-table/# - just not for browsers, rather for a given file to be checked against different implementations of JavaScript.
My guess is, that each version must have some specifics, which can be tested for. However, all I can find is stuff about "what version does this browser support".
PS: Don't take "now it is your job" literally, I used it to demonstrate the task, not to imply that I expect work done for me; while in the progress of solving this, it would be just nice to have some help or direction.
EDIT: I took the easy way out, by recquiring ECMAScript 5 to be supported at least as good as by the current FireFox for my projekt to work as intendet and expected.
However, I am still intereseted in any solution-attemps or at least an definite answer of "is possible(, with XY)" or "is not possible, because ..."; XY can be just some Keyword, like FrameworkXY or DesignPatternXY or whatever or a more detailed solution of course.
Essentially you are looking to find the minimum requirements for some javascript file. I'd say that isn't possible until run time. JavaScript is a dynamic language. As such you don't have compile time errors. As a result, you can't tell until you are within some closure that something doesn't work, and even then it would be misleading. Your dependencies could in fact fix many compatibility issues.
Example:
JS File A uses some ES5 feature
JS File B provides a shim for ES5 deficient browsers or at least mimics it in some way.
JS File A and B are always loaded together, but independently A looks like it won't work.
Example2:
Object.create is what you want to test
Some guy named Crockford adds create to Object.prototype
Object.create now works in less compatible browsers, and nothing is broken.
Solution 1:
Build or find a dependency map. You definitely already have a dependency map, either explicitly or you could generate it by iterating over you HTML files.
Run all relevant code paths in environments with decreasing functionality (eg: ES5, then E4X, then JS 1.x, and so forth).
Once a bundle of JS files fail for some code path you know their minimum requirement.
Perhaps you could iterate over the public functions in your objects and use dependency injection to fill in constructors and methods. This sounds really hard though.
Solution 2:
Use webdriver to visit your pages in various environments.
Map window.onerror to a function that tells you if your current page broke while performing some actions.
On error you will know that there is a problem with the bundle on the current page so save that data.
Both these solutions assume that you always write perfect JS that never has errors, which is something you should strive for but isn't realistic. This might; however, provide you with some basic "smoke testing" though.
This is not possible in an exact way, and it also is not a great way of looking at things for this type of issue.
Why its not possible
Javascript doesn't have static typing. But properties are determined by the prototype chain. This means that for any piece of code you would have to infer the type of an object and check along the prototype chain before determining what function would be called for a function call.
You would for instance, have to be able to tell that $(x).bind() o $(x).map are not making calls to the ecmascript5 map or bind functions, but the jQuery ones. This means that you would really have to parse out the whole code and make inferences on type. If you didn't have the whole code base this would be impossible. If you had a function that took an object and you called bind, you would have no idea if that was supposed to be Function.prototype.bind or jQuery.bind because thats not decided till runtime. In fact its possible (though not good coding practice) that it could be both, and that what is run depends on the input to a function, or even depends on user input. So you might be able to make a guess about this, but you couldn't do it exactly.
Making all of this even more impossible, the eval function combined with the ability to get user input or ajax data means that you don't even know what types some objects are or could be, even leaving aside the issue that eval could attempt to run code that meets any specification.
Here's an example of a piece of code that you couldn't parse
var userInput = $("#input").val();
var objectThatCouldBeAnything = eval(userInput);
object.map(function(x){
return !!x;
});
There's no way to tell if this code is parsing a jQuery object in the eval and running jQuery.map or producing an array and running Array.prototype.map. And thats the strength and weakness of a dynamically typed language like javascript. It provides tremendous flexibility, but limits what you can tell about the code before run time.
Why its not a good strategy
ECMAScript specifications are a standard, but in practice they are never implemented perfectly or consistently. Different environments implement different parts of the standard. Having a "ECMAScript5" piece of code does not guarantee that any particular browser will implement all of its properties perfectly. You really have to determine that on a property by property basis.
What you're much better off doing is finding a list of functions or properties that are used by the code. You can then compare that against the supported properties for a particular environment.
This is still a difficult to impossible problem for the reasons mentioned above, but its at least a useful one. And you could gain value doing this even using a loose approximation (assuming that bind actually is ecmascript5 unless its on a $() wrap. Thats not going to be perfect, but still might be useful).
Trying to figure out a standard thats implemented just isn't practical in terms of helping you decide whether to use it in a particular environment. Its much better to know what functions or properties its using so that you can compare that to the environment and add polyfills if necessary.

Why does eval() exist?

Many programmers say it is a bad practice to use the eval() function:
When is JavaScript's eval() not evil?
I'd like to take a moment to address the premise of your question - that eval() is "evil"...
Is this eval() dangerous?
Buggy evaled code can violate security properties just as easily as buggy source code...
Why not eval() JSON?
There are a number of ways that your security may be compromised...
Is there ever a good reason to use eval()?
Yes - when there is no other way to accomplish the given task with a reasonable level of clarity... This eliminates 99% of cases where eval is used...
Why is eval unsafe in javascript?
The danger of eval only rears its ugly head when you are serving a script written by alice to user bob for bob's browser to eval...
So why does it exist in the first place?
Because sometimes there is a need. All the same reasons for/against using eval in JavaScript can likely be shared with the use of reflection in Java, for example.
However, I agree with everything you quoted in your question. Many reasons for using it are ill-advised, and best done differently - but sometimes, there is still a need, or it is simply the "best choice" over other available alternatives. (I'd focus on the answers to Is there ever a good reason to use eval()? for additional reasons.)
+1 to your question for good research.
eval() exists because sometimes you want to give complete programmatic control of your application to code passed in at run time.
Languages without an eval() feature can definitely provide (a subset? all?) of this functionality by asking each programmer to essentially write their own eval() -- lex the input, parse the input, create new objects as necessary, run methods or functions on them via simple string comparisons or similar. In essence, duplicate the entire interpreter that already exists and is debugged and fast.
Eval is actually a powerful feature and there are some things that are impossible to do without it. For example:
Evaluate code received from a remote server. (Say you want to make a site that can be remotely controlled by sending JavaScript code to it?)
Evaluate user-written code. Without eval, you can't program, for example, an online editor/REPL.
Creating functions of arbitrary length dynamically (function.length is readonly, so the only way is using eval).
Loading a script and returning it's value. If your script is, for example, a self-calling function, and you want to evaluate it and get it's result (eg: my_result = get_script_result("foo.js")), the only way of programming the function get_script_result is by using eval inside it.
Re-creating a function in a different closure.
And anything else you'd want to do that involves creating code on the fly.
The reason it is considered "evil" is because it's classicaly used by novices to do things that the language can handle natively. For example, the code below:
age_of_erick = 34;
age_of_john = 21;
person = "erick";
eval("console.log('age_of_"+person+"')");
And the code below:
age = {erick:34, john:21};
person = "erick";
console.log(age["erick"]);
Both do the same thing, except one parses a string, generates code from it, compiles into machine code and then runs, while the other reads a value from a hash, which is a lot faster.
There's a research publication exacty on this topic:
The Eval That Men Do -- A Large-scale Study of the Use of Eval in JavaScript Applications
Mirror on Wayback Machine
It is to me the most comprehensive answer to this question to date.
Quote from the abstract:
We have recorded the behavior of 337 MB of strings given as
arguments to 550,358 calls to the eval function exercised in over
10,000 web sites.
Amongst other, they identified 9 categories of recurring eval:
JSON - A JSON string or variant.
JSONP - A padded JSON string.
Library -One or more function definitions.
Read - Read access to an
object’s property.
Assign - Assignment to a local variable or
object property.
Typeof - Type test expression.
Try - Trivial
try/catch block.
Call - Simple function/method call.
Empty -
Empty or blank string.
A snippet from the conclusion (which is too long to be quoted entierly):
[...] While many uses eval were legitimate, many were unnecessary and
could be replaced with equivalent and safer code. We started this work
with the hope that it would show that eval can be replaced by other
features. Unfortunately our data does not support this conclusion.[...]
A paper well worth reading.
The eval() feature is like scissors. You're an adult, it's your responsibility to not run with them.
I've seen the design philosophy of dynamic languages (like JavaScript) summarised as preferring to enable smart people to do clever things above trying to prevent stupid people from doing silly things. (Unfortunately I can't recall the original source or phrasing.)
If you're worried about introducing bugs with eval, you can use strict mode. It seems to prevent some of the problems with how the feature is designed. (That is, as a "magic" function allowed to clobber your namespace.)
Eval exists to simplify tasks in JavaScript. You can use it evaluate multiple statements. Instead of having to find another way you can use eval to do such things. Even though it is discouraged it has considerable power and use.

How do I safely "eval" user code in a webpage?

I'm working on a webapp to teach programming concepts. Webpages have some text about a programming concept, then let the user type in javascript code into a text editor window to try to answer a programming problem. When the user clicks "submit", I analyse the text they've typed to see if they have solved the problem. For example, I ask them to "write a function named f that adds three to its argument".
Here's what I'm doing to analyse the user's text:
Run JSLint on the text with strict settings, in particular without assuming browser or console functions.
If there are any errors, show the errors and stop.
eval(usertext);
Loop through conditions for passing the assignment, eval(condition). An example condition is "f(1)===4". Conditions come from trusted source.
Show passing/failing conditions.
My questions: is this good enough to prevent security problems? What else can I do to be paranoid? Is there a better way to do what I want?
In case it is relevant my application is on Google App Engine with Python backend, uses JQuery, has individual user accounts.
So from what I can tell if you are eval'ing a user's input only for them, this isn't a security problem. Only if their input is eval'd for other users you have a problem.
Eval'ing a user's input is no worse than them viewing source, looking at HTTP headers, using Firebug to inspect JavaScript objects, etc. They already have access to everything.
That being said if you do need to secure their code, check out Google Caja http://code.google.com/p/google-caja/
This is a trick question. There is no secure way to eval() user's code on your website.
Not clear if the eval() occurs on client or server side. For client side:
I think it's possible to eval safely in an well configured iframe (https://www.html5rocks.com/en/tutorials/security/sandboxed-iframes/)
This should be 100% safe, but needs a couple of libraries and has some limitations (no es6 support): https://github.com/NeilFraser/JS-Interpreter
There are lighter alternatives but not 100% safe like https://github.com/commenthol/safer-eval.
Alternatively, I think something similar can be implemented manually wrapping code in a with statement, overriding this, globals and arguments. Although it will never be 100% safe maybe is viable in your case.
It can't be done. Browsers offer no API to web pages to restrict what sort of code can be executed within a given context.
However, that might not matter. If you don't use any cookies whatsoever on your website, then executing arbitrary Javascript may not be a problem. After all, if there is no concept of authentication, then there's no problem with forging requests. Additionally, if you can confirm that the user meant to execute the script he/she sent, then you should also be protected from attackers, e.g., if you will only run script typed onto the page and never script submitted via GET or POST data, or if you include some kind of unique token with those requests to confirm that the request originated with your website.
Still, the answer to the core question is that it pretty much is that it can't be done, and that user input can never be trusted. Sorry :/
Your biggest issue will always be preventing infinite loops for occurring in user-provided code. You may be able to hide "private" references by running eval in the right context, e.g.:
let userInput = getUserInput();
setTimeout(() => {
let window = null;
let global = null;
let this = null;
// ... set any additional references to `null`
eval(userInput);
}, 0);
And you could wrap the above code in a try/catch to prevent syntax and logic errors from crashing outside of the controlled eval scope, but you will (provably) never be able to detect whether incoming user input defines an infinite loop that will tie up javascript's single thread, rendering its runtime context completely stalled. The only solution to a problem like this is to define your own javascript interpreter, use it to process the user's input, and provide a mechanism to limit the number of steps your javascript interpreter is willing to take. That would be a lot of trouble!

multi-core programming using JavaScript?

So I have this seriously recursive function that I would like to use with my code. The issue is it doesn't really take advantage of dual core machines because js is single threaded. I have tried using webworkers but don't really know much about multicore programming. Would someone point me to some material that could explain how it is done. I googled to find this sample link but its not really much help without documentation! =/
I would be glad if someone could show me how this could be done without webworkers though! That would be just awesome! =)
I came across this link on whatwg. This is really weird because it explains how to use multicore programming in webworkers etc, but on executing on my chrome browser it throws errors. Same goes with other browsers.
Error: 9Uncaught ReferenceError: Worker is not defined in worker.js
UPDATE (2018-06-21): For people coming here in search of multi-core programming in JavaScript, not necessarily browser JavaScript (for that, the answer still applies as-is): Node.js now supports multi-threading behind a feature flag (--experimental-workers): release info, relevant issue.
Writing this off the top of my head, no guarantees for source code. Please go easy on me.
As far as I know, you cannot really program in threads with JavaScript. Webworkers are a form of multi-programming; yet JavaScript is by its nature single-threaded (based on an event loop).
A webworker is seperate thread of execution in the sense that it doesn't share anything with the script that started it; there is no reference to the script's global object (typically called "window" in the browser), and no reference to any of your main script's variables other than data you send to the thread.
Think as the web worker as a little "server" that gets asked a question and provides an answer. You can only send strings to that server, and it can only parse the string and send back what it has computed.
// in the main script, one starts a worker by passing the file name of the
// script containing the worker to the constructor.
var w = new Worker("myworker.js");
// you want to react to the "message" event, if your worker wants to inform
// you of a result. The function typically gets the event as an argument.
w.addEventListener("message",
function (evt) {
// process evt.data, which is the message from the
// worker thread
alert("The answer from the worker is " + evt.data);
});
You can then send a message (a String) to this thread using its postMessage()-Method:
w.postMessage("Hello, this is my message!");
A sample worker script (an "echo" server) can be:
// this is another script file, like "myworker.js"
self.addEventListener("message",
function (evt) {
var data = JSON.parse(evt.data);
/* as an echo server, we send this right back */
self.postMessage(JSON.stringify(data))
})
whatever you post to that thread will be decoded, re-encoded, and sent back. of course you can do whatever processing you would want to do in between. That worker will stay active; you can call terminate() on it (in your main script; that'd be w.terminate()) to end it or calling self.close() in your worker.
To summarize: what you can do is you zip up your function parameters into a JSON string which gets sent using postMessage, decoded, and processed "on the other side" (in the worker). The computation result gets sent back to your "main" script.
To explain why this is not easier: More interaction is not really possible, and that limitation is intentional. Because shared resources (an object visible to both the worker and the main script) would be subject to two threads interfering with them at the same time, you would need to manage access (i.e., locking) to that resource in order to prevent race conditions.
The message-passing, shared-nothing approach is not that well-known mainly because most other programming languages (C and Java for example) use threads that operate on the same address space (while others, like Erlang, for instance, don't). Consider this:
It is really hard to code a larger project with mutexes (a mutual exclusion mechanism) because of the associated deadlock/race condition complexities. This is stuff that can make grown men cry!
It is really easy in comparison to do message-passing, shared-nothing semantics. The code is isolated; you know exactly what goes into your worker and what comes out of your worker. Deadlocks and race conditions are impossible to achieve!
Just try it out; it is capable of doing interesting things, probably all you want. Bear in mind that it is still implementation defined whether it takes advantage of multicore as far as I know.
NB. I just got informed that at least some implementations will handle JSON encoding of messages for you.
So, to give an answer to your question (it's all above; tl;dr version): No, you cannot do this without web workers. But there is nothing really wrong about web workers aside from browser support, as is the case with HTML5 in general.
As far as I remember this is only possible with the new HTML5 standard. The keyword is "Web-Worker"
See also:
HTML5: JavaScript Web Workers
JavaScript Threading With HTML5 Web Workers
Web workers are the answer to the client side. For NodeJS there are many approaches. Most popular - spawn several processes with pm2 or similar tool. Run single process and spawn/fork child processes. You can google around these and will find a lot of samples and tactics.
Web workers are already well supported by all browsers. https://caniuse.com/#feat=webworkers
API & samples: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers

Categories