What risk or liablities in using eval() in the following manner - javascript

I'm working on creating one of those robot games. The user creates a robot and then puts it in a battlefield with other robots.
I'd like to let the users use javascript to program their bots. I'll provide a number of functions for them to call, but they also can build thier own. (sorta)
To date, the only solution I have come up with is to use the javascript eval() function to execute the code the users have written.
I want to know two things:
Anyone have any alternative suggested implementations that still allow the users to write in javascript?
Can the users do anything with this flaw that they could not do using the firefox javascript debugging tools? (ie: on their own without my use of the eval() function)
Note: The javascript code is stored within mySQL. ajax is used to pull the jscript out and display to users. ajax is used to send javascript updates back into SQL. All code submitted by users and about to be inserted in the database is run through a "clean()" function.

So basically you will allow UserA to write javascript which will be evalled in UserB's browser?
If so, then that sounds like a fairly bad idea ;)
You could use a middle layer such as http://code.google.com/p/google-caja/wiki/CajaCajole to make it a bit safer.
An example of what they could do is: write javascript which will present what looks like your login page, then send the username and password to another server.
Another example would be to inject a script tag which then gets the 'full' payload which could get up to all kinds of mischief, like fx showing a friendly popup with the new exclusive downloadable Portal game that you got a special deal with Steam to make available etc etc. Just download and Run! Then it creates a hidden iframe to some trojan cdn. :)

I never thought I'll say this, but Project Narcissus might be of use to you. It's a JavaScript engine written in JavaScript.

Cool idea.
eval does have a slight disadvantage against other methods of script injection.
You can create a function on the fly with Function. Try this:
var command = "alert(123)";
var doStuff = new Function(command);
doStuff();
eval runs in the private scope, Function runs in the global scope. That means if you have an internal value that bots aren't supposed to be able to modify, they might have access to it if you run their logic through eval, but they shouldn't if you use Function. More info here:
changing string to a function in javascript (not eval)

Many AJAX libraries can be set to execute the returned JS automatically. No need for eval().

The most important thing is to let pages containing user scripts run on a separate, "sandboxed" domain that has no session cookies from the main site that could be connected to user accounts and such.
That, together with some manual monitoring of the submissions, will already take away a lot of the script injection risks.
There will always be some risk of malicious code being run on the user's browser when allowing Javascript from your users, but it stands to reason that getting malicious JavaScript is a general risk on the Internet, and it's up to the client to protect against it.
What I wouldn't do is eval() user-entered JavaScript inside the main domain of the project. That opens too many real dangers of attack.

Related

Check JavaScript before submitting / Deny access to global variables

I have made a math formula editor which allows the user to enter a math formula. This will then be converted to a JavaScript equation in a string, which will be executed using eval(). The user will also be able to submit it so that other users can view his function. The big problem with this is that it would be possible to enter JavaScript code in the formula, which would then be executed by the browsers of other users viewing it. I unfortunately can't just escape the formula because I am converting things like Sinus to a Math.sin() function. I am open to any suggestions how I can prevent the user from putting JavaScript code into the Math formula, here are my ideas:
Somehow check the code. The problem is that as said I can't just scan for any JavaScript function because I am using things like Math.sin() or Math.log(). So I would like to allow any method of the Math object and also normal math using standard operators. Another problem with this is that JavaScript can be disabled and modified, which could be a security concern. It would therefore be great if I could do this scanning using PHP.
Execute the equation in a "safe environment". Now I don't know if this is possible in JavaScript, but I am basically looking for something where the function that is being executed can't access or modify any functions (except any methods of the Math object) and can't change any of the global variables, including the document variable. I don't know whether this is possible or not but maybe somebody knows something.
Thanks for your help, Moritz
UPDATE: I have found a way. I made a function which shadows all global variables and functions with a local variable. This is the function:
function safeEval(string,banned) {
for(var i=0;i<banned.length;i++) {
eval('var '+banned[i]);
}
return eval(string);
}
Where banned is an array of strings which will be shadowed. To block all global variables, you can call it like this:
safeEval('document.write("test")',Object.keys(window))
This will throw an error, which is exactly what I want. Object.keys(window) will return an array of all global variables (and functions), including safeEval.
ANOTHER UPDATE: As Rainer Plumer pointed out, this is not safe as you can use this as follows: safeEval('this.document.write("test")',Object.keys(window))
Hope I could help. Moritz
The "safe environment" is a good idea; It can achieve by Iframe.
According to your description, you need a "safe environment" to run a JavaScript equation, I think Iframe is very good to do that. This process runs a JavaScript equation can be done in Iframe, and it is safe because the page and Iframe are independency document.
Then you can use postMessage or something else to get result from Iframe, show it to users. You have to use another domain in Iframe that can ensure nobody can get users cookie or something else important, one of the famous website is codepen.io doing that.

client side scripting language that enables storing data

I am creating a browser extension that has to store data.
I am going to have the client side language read from the page which is a game,
and save data if mistakes were made , or the data is not already accessible.
basically i'm trying to make a bot for a choice decision game when the
posibilities and the questions are built in.
since the possibilities are final I would really like it if in some way i would be
able to actually make the bot play for an hour and then have a file containing
the entire game's deicisions.
well , I can't do that with javascript since it disables storing data,
am I able to do it with another language which has access to the html DOM?
I have no problem to even use some language that wasn't supposed to do that
and then write a small library for DOM accessibility, as long as it allows DOM
access, I have no idea which though.
edit: I haven't noticed I actually got answers to this. I realize the question is very vague(it's a very old one), but basically, I just built a simple html parser via python. I asked a friend of mine how I could build a bot, he said he simply did it by creating a browser extension, and I decided I'll give it a shot. anyways, yes, I should've resourced more into the browser's api and check for a way to store client's data.
I'm not sure to clearly understand what you want to do but maybe you could use the local storage of your browser with Javascript. It's a simple way to store a little amount of data in a webApp context.
EDIT 1 :
Here's a little sample to help you :
// Store
localStorage.score = 5000;
// Retrieve data
var score = localStorage.score;

How can I prevent someone from altering or avoiding my JavaScript logic when adding buttons to jQuery UI dialog?

I am using a jQuery UI dialog and I am adding buttons to the dialog in JavaScript based on some entitlements logic. (I pass in a boolean from my server-side AJAX call if I am entitled and then I show different buttons based on that flag.)
What concerned me is what is preventing someone from using developer tools like Firebug and putting a breakpoint on that line that does the check and either altering the flag or dragging to skip over that entitlements check.
So my question is specific to adding buttons onto a jQuery UI dialog (because its not like you can add the buttons from the server side since its a jQuery plugin), but I guess it highlights a more general point around any entitlements logic on the client side being "vulnerable". So if there are any general best practices around this point I would be interested (but still looking for an answer to my specific example).
NOTE: I am also doing a server-side entitlement check on POST as a backup, so I am still "protected" but I am still concerned about the point above.
Nothing prevents people from altering client-side code, it is inevitable.
You can, however, add buttons of the kind of "server-side", you just retrieve a string using the AJAX call, which happens to be a JavaScript function that adds buttons. And on the client side do eval() on that string which will execute the retrieved JS function and will add the buttons. Moreover, you can transmit your entire JavaScript code that way, so the client cannot skip anything since all is being executed in the eval().
A quick example:
Server-side function returns
string banana= "alert('test');";
return banana;
and client side does
eval(response.d);
Here is a theoretical example: FIDDLE
You cannot control what clients will do with your scripts, nor what requests they will make of your server. You must design your back-end API (not your JS client) to be the "gating mechanism" between the user and your system. It's best not to think of the JS as part of your system, but as a separate client that you ship as a reference implementation for your API.
But, if you wanted to at least make it difficult for users to mess with your code, you could minify and concatenate your JS scripts with something like Closure.
As the other person suggested, you cannot implement security on the client for exactly the reason you point out. You could use basic auth, or try setting up a token based approach.

Ways to make Javascript code hacking / injection / manipulation difficult?

Are there ways to prevent, or make it difficult enough, for someone to inject Javascript and manipulate the variables or access functions? A thought I had is to change all var names randomly on each reload so the malware script would need to be rewritten every time? Or are there other less painful ways?
I understand that eventually someone will hack his way in, but I'd like to know ways to make it difficult to reproduce the action, so that people won't publish a bookmarklet or something similar for everyone to use. I don't care if experts find their way in the code, but I'd like it to be a bit more complex than javascript:d=0;
If you know ways to make hacking Javascript a bit more difficult, please write those.
Accept that your javascript will be "manipulated" and make provision at the server side. There's fundamentally nothing you can do to stop people tinkering with the client.
You can write your JS to use only private methods and variables in a self-executing function. For example, the following code leaves no sign of itself in the global namespace for anyone to monkey with.
(function(){
var x = 1;
var y = 2;
var z = "A am z";
var clickHandler = function() {
alert('You clicked the body');
};
document.getElementsByTagName('body')[0].addEventListener('click',clickHandler,true);
}());
[EDIT]
The above code is susceptible to a user overwriting any globally available objects, methods, events or properties you are using (in this case, document, getElementsByTagName and addEventListener), so if you are truly paranoid you can copy these to your function scope before the page has loaded and the user has a chance to overwrite them. Using addEventListener is a good idea because unlike the event body.onclick, it cannot be removed or overwritten from outside the function.
Any user that will really want to tamper with the client will be able to. The code is on his machine. Even if you obfuscate the client side code, there are tools out their that will help someone deobfuscate the code back in a second.
What you need to think about though is making the site safe on the server, and safe for other users as well.
This means (as a minimum):
Checking/Validating every request and input parameters on the server so Users won't be able to alter any server side data by triggering 'hacked' client side functions you wrote.
Check all data that you output to the screen that was originated from user input. Other users might have inserted client side scripts that are dangerous for your site, and especially dangerous to the other users on your site. (If you're using .net then check out the AntiXSS library)
Obfuscation and minification should make it a good bit more difficult to hack, but I agree with spender.

Javascript bridge to Flash to store SO "cookies" within flash

After reading this on the question How do I uniquely identify computers visiting my web site?
:
A possibility is using flash cookies:
Ubiquitous availability (95 percent of visitors will probably have
flash)
You can store more data per cookie (up to 100 KB)
Shared across browsers, so more likely to uniquely identify a machine
Clearing the browser cookies does not remove the flash cookies.
You'll need to build a small (hidden)
flash movie to read and write them.
I tried to find if someone has already done something like this, so I wouldn´t have to reinvent the wheel. So far, no luck(maybe I don´t know the right term to search), except for the code in the flash side
The use I have for this is to prevent a user to answer a quiz multiple times, but future uses maybe banning trolls.
Does anyone knows a open source library that does this and allows me to access via javascript?
Caveats: I don't know flash and I don't own a license.
Edit: You can do that using evercookie. It's kind of evil, but works.
To build on what rmeador said, and to help get you started, you are going to need to know how to use two classes in the FLEX3 API, SharedObject and ExternalInterface.
SharedObject will allow you to store and retrive data from a client computer and ExternalInterface will allow your actionscript to communicate with your javascript.
Using shared object is simple.
To put data onto a users machine just create a SharedObject and add properities to the sharedObject's data properity.
private var sharedObject : SharedObject = SharedObject.getLocal("myCookie");
sharedObject.data.DATA_FOR_THE_COOKIE = DATA;
Retriving data from the SharedObject is just as simple. Make sure the size of the SharedObject is greater than 0 (Make sure the SharedObject exists) and the just look up the properity names through the SharedObject's data properity.
if(sharedObject.size > 0)
// access data from cookie with -> sharedObject.data.DATA_FROM_THE_COOKIE;
To pass the data stored in the SharedObject to your javascript you are going to need to use ExternalInterface.
Lets say you have a javascript function to retrieve the variables
function retrieveVars( vars ){
// Do something with vars.
}
To call this function from actionscript you will use
ExternalInterface.call("retrieveVars", DATA_ITEM_1, DATA_ITEM_2, ...);
Its that simple.
Please note that this technique will not work if the client's flash player has its storage settings set at 0, or if the client's browser does not have ActiveX or NPRuntime.
I'm hesitant to answer your question, because it sounds like this is straying dangerously close to Evil... Also, it's doomed to failure. If you really want to prevent a user from answering a quiz multiple times, the best thing you can do is have them register a user account. If you want to prevent them from registering multiple user accounts, you can have them verify something through a credit card or snail mail, both of which are generally untenable solutions. In short, the internet is anonymous.
Anyways, if you really want to go forward with this plan, you can build your application in Flex (a variant of Flash) fairly trivially. There's tons of documentation on the Adobe site. Some of it is rather sparse and annoying, particularly the collections API, but it'll be sufficient for your purposes. ActionScript (the programming language underlying both Flash and Flex) is very much like JavaScript and easy to learn. Flex has a free SDK (usually available in a small link from the page that tells you to get the expensive Flex Builder; Flex Builder is a primarily GUI tool, whereas you'll be writing straight code without an IDE with just the SDK), so a license shouldn't be a problem. The JavaScript to Flash bridge is also well documented.
BakedGoods seems to be exactly what you need (or rather, what you did need); its a Javascript library that establishes a uniform interface that can be used to conduct common storage operations in all native, and some non-native storage facilities, including Flash Locally Shared Objects (the "cookies" you speak of).
With it, creating an LSO can be accomplished with code as simple as:
bakedGoods.set({
data: [{key: "key", value: "value"}],
storageTypes: ["flash"],
complete: function(byStorageTypeRemovedItemKeysObj, byStorageTypeErrorObj){/*code*/}
});
Retrieving and removing data is just as easy. Trust me on all of this, I would know; i'm its maintainer :)
If for whatever reason you'd prefer to roll out your own solution, rmeador and ForYourOwnGood have supplied you with enough information to help you get started.
They've forgot to tell you how to do one very important thing, however: how to access, with Javascript, the Actionscript code that will handle the Shared Objects.
First, you will need to encapsulate your ActionScript code in a method, and then register that method as part of the ExternalInterface of its parent application:
function handleObjects(/*param1, param2, ... */):void {/*code*/}
ExternalInterface.addCallback("handleObjects");
Second, you will need to compile your Actionscript application (your code), and create an element in your HTML that references the resultant .swf file.
Then, assuming the aforementioned HTML element is represented as a DOMElement named flashDOMElement, you can call your method with the DOMElement:
flashDOMElement.handleSharedObjects(/*arg1, arg2, ... */);
And that's it! There are a couple of things that we've failed to mention or skimmed over, but all in all, rolling out your own solution is not hard. Rolling out your own reliable solution, however, is a different matter, which is partly why I suggest you use BakedGoods.
For people searching for this now, be sure do check out evercookie.
Evercookie definitely gets the job done, but this is a little closer to what you were originally asking for: https://github.com/nfriedly/Javascript-Flash-Cookies MIT license.

Categories

Resources