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.
Related
Is it possible to detect if - let's say - someone uses firebug to change parts of the website that's been loaded.
E.g. I got <a href="javascript:myfunc('hello')"> and someone changes that to <a href="javascript:myfunc('NOThello')">. Can I immediately detect this change somehow?
Thank you.
No, you cannot.
You could obviously write code to check to see if something was the way you wanted it to be, but guess what? People could change that very code to bypass the detection. Web pages are complete insecure. You cannot trust anything in them. They can be easily altered - any part of them can be altered including HTML, javascript, etc... And, using debuggers is not the only way to alter web pages - there are many different techniques including things like active proxies.
You MUST verify and check on the server anything that is being submitted to a server because you simply cannot trust its origin. For example, people use client-side javascript to validate data that is entered into forms all the time, but this is ONLY done to improve the user experience if something is entered incorrectly (so you can more easily tell the user something is wrong BEFORE the data is submitted to the server). All validation checking must also be done on the server to make sure that only valid data gets into your server.
Ah, right, you're just curious about how to do that!
I can't reproduce your test case, but here are the options I see:
using a recursive setTimeout or setInterval checking when the element has been altered, but that is highly slow and ugly
using mutation observers, and unset the changes
Florent
In my previous question:
Securing javascript game timing
... it became clear that client-side timing in a Javascript/Canvas game simply won't be secure. I know the mantra about not trusting the client - that is what is causing my struggle in the first place. :-)
So, if I do move all timing to the server and just deal with it, here is a follow-up question. The game obviously needs to be completed before submitting it. As the game puzzle is all Javascript, this introduces the problem of manipulating the client-side code to fake the completion of the game.
I've created the game JS code in a separate class file. If I instantiate the game as such:
var game;
$document.ready(function(){
game = new Game();
});
... then, I can access the 'game' object and all of its methods and variables via the console.
However, if I do:
$document.ready(function(){
var game = new Game();
});
... then I cannot access the 'game' object through the console. This seems to help, but is there something I don't know - can this object still be accessed in some way I don't know about or is making it a private var in that function a little more secure?
Thanks!
Note: there are many other security considerations and attack vectors in such a system. This answer just seeks to answer the specific question that was asked here.
It depends on the browser and what its devtools provide. Most browsers' devtools provide functionality to:
pause execution of JavaScript at any point in time and use a debugger interface.
variables that are in-scope at the current point of execution where the debugger is paused can usually be accessed via devtools in various ways. Inparticular, via console, where anything one can do with that variable in the console is fair game: query its fields, call its methods, etc. If the variable binding isn't const, one can even reassign the variable to a new user-created instance of the object.
navigate JS files and set breakpoints in them.
this is a vector to the above bullet point.
you can make this less attractive by using JS minification (ie. obfuscation), but that's not going to stop someone who's determined.
String literals don't get minified and can usually help a lot in navigating and understanding minified code.
inspect event listeners on HTML elements and set breakpoints on them.
If a variable has a reference bound to it in a function closure that is known to be an event listener of a certain HTML element, or reachable (execution-wise) by such an event listener, this can be another vector to the first bullet point. This can be very common in web games. Just a keyboard event listener usually is an entry-point to reach functions that reference important game objects.
There are even tools to record the JS heap memory. It's a lot of data to sift through, but it's basically everything on the JS heap (readonly).
Given those browser features (and the fact that a user can use any browser they wish), it's impossible to "safeguard" anything 100% on the client-side. It's a losing battle. If you want to play it like a game, you can do your best.
Look into Object.freeze and friends.
freeze or seal anything that can be frozen or sealed, including class prototypes
make variables which can be const const
use assertions to assert in critical parts of the logic that the program state is consistent and try to detect tampering.
Don't care too much about the console. Yes, if there are global objects whose method can easily be fired to "win" the game, it's a nice possibility to cheat, but it can easily prevented as you demonstrated.
So, the hacker would just listen (look at the network pane) which requests are made to your server and fire them manually. If they were just some simple urls like /action=start and /action=end, he could very easily fire them manually without any timing. So you will need to prevent that (although you never can really make it safe), e.g. by adding additional credential tokens. Or you could embed some "secret"(s) into the game code, which are revealed during the gameplay, and need to be sent to the server to prove the rightfulness. Of course they could be read out of your code, but you have to make it too complicated for the hacker. It's a bit like security by obscurity…
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.
My background is in C and I've picked up PHP, mySQL, HTML, CSS without too much issue.
But I'm finding Javascript/jQuery surprisingly difficult to get right.
Very frustrating.
Why?
It seems to violate a number of traditional programming principles (e.g. variable scope)
Undefined variables seem to appear out of nowhere and already have values associated with them. For example (from the jQuery docs):
$("a").click(function(event) {
event.preventDefault();
$('<div/>')
.append('default ' + event.type + ' prevented')
.appendTo('#log');
});
What exactly is "event"? Do I have to use this variable name? Should I just assume that this object is magically instantiated with the right stuff and I can use any of the methods list at the JQuery API?
There seems to be bunch of random rules (e.g. return false to stop a default action, but sometimes this doesn't work?)
Non-deterministic behavior when debugging. (e.g. I refresh the browser, try something and get result X for JS variables I'm watching in Firebug. I refresh again and I get result Y?)
Very messy looking code that is hard to follow. What happens when? I'm using Firebug and Chrome Developer Tools, but I'm not getting enough visibility.
It seems like everyday there's some random JS "rule" that comes up that I've never seen before in any of my JS books or tutorials.
What do I need to do to make Javascript/jQuery more deterministic, controlled, and logical to me?
Are there any resources that explain Javascript's quirks/gotchas?
Thanks!
1) It seems to violate a number of traditional programming principles (e.g. variable scope)
You need to declare variables using var, else it will go into the global scope.
2) Undefined variables seem to appear out of nowhere and already have values associated with them (how did this happen?)
This is possibly related to 1) and/or 4).
3) There seems to be bunch of random rules (e.g. return false to stop a default action, but sometimes this doesn't work?)
You need to let the handler return false as well. E.g. form onsubmit="return functionname()". You also need to return from the "main" function, not only from a closure (a function inside a function), referring to your previous question. It would only return into the "main" function and continue on.
4) Non-deterministic behavior when debugging. (e.g. I refresh the browser, try something and get result X for JS variables I'm watching in Firebug. I refresh again and I get result Y?)
Probably the code was executed before the HTML DOM was finished populating. You need to hook on window.onload or $(document).ready() whenever you want to execute stuff during page load.
5) Very messy looking code that is hard to follow. What happens when? I'm using Firebug and Chrome Developer Tools, but I'm not getting enough visibility.
I bet that you're talking about jQuery source? It's just a large library. You should after all not worry about this when debugging. Rather worry about your own code. However, make sure that you're looking at the unminified version of jQuery's source code.
See also:
JavaScript: the bad parts
What should every JavaScript programmer know
Douglas Crockford's "Javascript: The Good Parts" was an invaluable resource. Javascript plays a lot more like Lua, Lisp, or Python than C, it just happens to LOOK like C.
Link provided to Amazon; I snagged mine from O'Reilly.
To be honest, I think you have a good understanding. Some of my hangups were similar. The way that I have been moving on is "well, if that's the way it is, then that's the way it is". Just accept the idiosyncrasies and plow forward. PHP does some of the same things (variables can show up out of nowhere, etc...). Just code the way you want to code and if it works, then great!
Then after you get to that point start breaking out the profiler and see if there's anything that you can optimize.
Here are a couple of things:
If you understand CSS, then jQuery selectors should be easy. As far as the code goes, that's straightforward too if you can deal with chaining and JSON. EDIT: also, the jQuery documentation on everything is EXCELLENT! And There is no shortage of jQuery experts here on SO to help us noobs (and hopefully we can return the favor for newer noobs).
There is a scope to work with. (Basically) anything written outside of a function or object is in global scope. If you are inside of an object or function and use var then that sets the variable's scope
Javascript isn't like a C-based language (C++ or PHP even). It uses prototypes to deal with class/object relationships rather than a subclassing scheme.
The #1 thing that threw me for a loop is that any JS that appears anywhere on the page or that was included in <script> tags is fair game. If you have a global variable in one script, you can use that same variable in a completely different script and it will work. That may be what you mean about variables showing up out of nowhere. Also, there are some DOM based variables that can just "show up" too.
Anyways, I think that if you just plow ahead, you'll get some "AHA" moments. I'm a relative noob to programming, but I continually grow as long as I don't hang up on something that doesn't have too much of an impact on actually making the code run.
It's a language based on prototypal inheritance and is influenced by functional programming languages and the paradigm so it isn't completely just OO/Procedural like other languages. Variables are implied globals unless declared with var.
Please include an example?
return false exits out of the function as with any language's return statement. preventDefault() would be the DOM method to cancel the default behaviour of a link
Javascript is used primarily on the client side. Since there are many user agents, each of them have a different implementation of the DOM, which is very inconsistent, moreso than JS itself. Again, please include a real example to get a definitive answer.
You'll find messy looking code in any language, and maybe your lack of understanding perceives the code as messy, when in fact it isn't so bad. Or maybe you're looking at some minified/obfuscated code.
I recommend http://eloquentjavascript.net/ for learning aspects of Javascript.
Things you'll learn from the link above
lambdas
closures
Prototypal inheritance
Event based programming
Debugging
DOM
"JavaScript: The Good Parts" by Douglas Crockford is a good start
In your case, the appendices ("the bad parts" and "the awful parts") might be the most interesting :)
Crockford's "Javascript: The Good Parts" gives some common JS patterns that help with variable privatization and scoping. This is for javascript in general. For jQuery I just use the API. Also the Yui Theatre videos on javascript are quite good
Javascript can be a little tricky and some of it's functional aspects confuses people. If you actually learn and understand the language you'll find it really useful, most people just randomly start using it and then just hate.
Read javascript the good parts by crockford, it's really helpful: http://javascript.crockford.com/
Also make sure you understand closure. It's a fundamental that people don't get but often use.
In terms of variable scope, there are local and global variables. One of the gotchyas of variable scope can be seen in this example:
var thisIsAGlobalVariable
function anon () {
var thisIsALocalVariable
thisIsAGlobalVariable = 5; //if you don't use the var prefix inside a fn, it becomes global
}
You are finding it difficult because:
javascript has another kind of syntax.
javascript is dificult to debug
javascript has no autocompletion like c# etc) ?or does it
javascript has illogical rules (they become logical once you are known with them)
everything can be done in 1000 ways, and when you search for a solution, you will find 2000 answers :) where c#, php mostly have a good practice function u "should/could" use
However, I started using js/jquery a half year ago, with the same reasoning as you do, and I stuck to it, and now I use it daily to enhance my webapps.
I just love it (especcially jquery). It is a life saver, I know what and where to look, I can do about anything with it.
Everything seems logical.
If I can give you one advice: javascript/jquery is a sour apple, but just hang in there, bit trough and you won't regret it.
also, a loooot of people use it and are always willing to lend a hand if needed (I know I do)
Javascript is tricky. You don't have a compiler watching your back. To compensate, unit testing becomes more important. I've been doing my unit testing with jQuery/QUnit, but I recently started using Jasmine (http://github.com/pivotal/jasmine) and I recommend it 200%. Its a great testing framework.
If you're not familiar with testing, or testing with javascript, I'd highly recommend finding unit tests for other OSS javascript projects (hopefully for code you could use) and seeing how they test it.
With unit tests, you'll make the same mistakes, but catch them much sooner and with less grief. And if your tests are good, the mistakes won't come back after you fix tham.
I don't know how much UI design you have done in C, but the event variable only shows up when it is sent by the caller and the handler needs to, well, handle the object. If you do reading on event object, the confusion in q #2 should go away.
There is no event handling in PHP, so I think you have not came across this issue in the past. JavaScript is a programming language with its own purpose, so it was designed to work for that specific purpose.
Maybe you have to link your code to an HTML onclick="event()" button to fire off as the event.
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.