I am developing a JS game and wish to prevent cheating as much as possible. I understand that this is near impossible but I would like to prevent users from going into the console and changing their lives by saying something like game.lives = 99;
Is there a way I can detect if a variable such as lives has been changed from the console thus marking the game hacked and stopping the execution of my code? I understand I could do server side checking but I want to avoid lag. I am looking for a JS answer if there is one.
You won't be able to completely stop a user from changing the javascript code or variable values. You only can make it more difficult. Fisch mentioned using closure so as all variables will be private. Look into the immediately invoked function expression (IIFE) pattern. It's used in a lot of plugin style code and helps prevent modifications.
If a user wants to change a variables value, nothing will stop them from running the game in debug mode and modifying values at breakpoints.
You could use a closure which would essentially make all your variables private and thus not accessible from the console. If you need to have some public variables and methods, you could use a revealing module pattern. you can read more about them here: http://www.joezimjs.com/javascript/javascript-closures-and-the-module-pattern/
Related
I watch a lot of programming tutorials and challenges using HTML5 canvas and Javascript (mainly by Dan Shiffman or The Coding Train) and I try to follow along while changing the code in order to make it my own.
I've noticed a lot of the programmers creating variables (e.g. let num;) and then assigning the values inside of an init() function.
What is the difference between doing that and just assigning the value to the variable in the same line (e.g. let num = 1;)?
I've tried doing both and I don't see a difference so I'm thinking it's maybe a slight performance boost?
Assigning the values inside a function will allow you to call that function from anywhere, rather than being stuck at assigning only at the initialization location. From a practical perspective, assuming you understand scope and the temporal dead zone, this can be helpful for:
Code organization. If you put the meat of your code into functions and then call the functions all together later, it can be easier to visualize the higher-order process of what's going on, and in what order the various chunks of code need to run in. If the code is long, it can be easier to understand what init() means than to understand what <200 lines of setup code> means.
Less repetitiveness. Say that at some point when the application is used, either you or the user want to reset the state of the app back to how it was originally. (For example, a "Play Again" button on a game.) Then, rather than having to write <200 lines of setup code> again, you'd just have to write init() again.
maybe a slight performance boost?
This has no effect on performance.
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.
I'm a habit driven creature, and console.log/console.error/etc happens to be the thing I just instinctively use to print things out. However, I'm trying to drive all my logging in node to 'winston'. I'd prefer to do something like var console = require('./modules/logger'); at the top of my file and then just use console.whatever as usual.. tapping into extra arguments as necessary (otherwise the api is pretty much the same). Since this is localized to the file I'm working with and not some sort of global change, is there any danger in setting 'console' to that module's export? And not just "well, it might be confusing for someone else".
I did notice this question pop up as a similar question, but it doesn't really answer whether there's a danger behind it. And there's some other questions that ask if you can override some of node's core, but I'm not doing that - I'm just making a local reference using the same name as a "magic" global.
Other than possibly overriding existing console functions in a non-standard (i.e. unexpected) way, I do not see any danger in replacing the global console with your own object as long as it provides all the expected functions and calling conventions (function signatures) as the default console. I've done it many times without issue.
If you do provide some non-standard implementation of an existing function on the global console with a different signature than other code expects, you're bound to run into problems.
If you do your replacement in a module or function scope, only references in that scope would be affected.
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…
My JavaScript is pretty nominal, so when I saw this construction, I was kind of baffled:
var shareProxiesPref = document.getElementById("network.proxy.share_proxy_settings");
shareProxiesPref.disabled = proxyTypePref.value != 1;
Isn't it better to do an if on proxyTypePref.value, and then declare the var inside the result, only if you need it?
(Incidentally, I also found this form very hard to read in comparison to the normal usage. There were a set of two or three of these conditionals, instead of doing a single if with a block of statements in the result.)
UPDATE:
The responses were very helpful and asked for more context. The code fragment is from Firefox 3, so you can see the code here:
http://mxr.mozilla.org/firefox/source/browser/components/preferences/connection.js
Basically, when you look at the Connect preferences window in Firefox, clicking the proxy modes (radio buttons), causes various form elements to enable|disable.
It depends on the context of this code. If it's running on page load, then it would be better to put this code in an if block.
But, if this is part of a validation function, and the field switches between enabled and disabled throughout the life of the page, then this code sort of makes sense.
It's important to remember that setting disabled to false also alters page state.
(Incidentally, I also found this form very hard to read in comparison to the normal usage.
Not necessarily, although that was my first thought, too. A code should always emphasize its function, especially if it has side effects. If the writer's intention was to emphasize the assignment to sharedProxiesPref.disabled then hey, roll with it. On the other hand, it could have been clearer that the action taking place here is to disable the object, in which case the conditional block would have been better.
It's hard to say what's better to do without more context.
If this code being executed every time that proxyTypePref changes, then you're always going to need set shareProxiesPref.disabled.
I would agree than an if statement would be a bit more readable than the current code.
Isn't it better to do an if on proxyTypePref.value, and then declare the var inside the result, only if you need it?
If you're talking strictly about variable declaration, then it doesn't matter whether or not you put it inside an if statement. Any Javascript variable declared inside a function is in scope for the entire function, regardless of where it is declared.
If you're talking about the execution of document.getElementById, then yes, it is much better to not make that call if you don't have to.