Even though, I am not a JS newbie, I still have never used (function() {}) before as there was no need. But now I am concerned with security on userside level for my JS game to avoid cheating. So what I did is I placed the following code in my js file:
(function() {
'use strict';
let a = 1;
});
I tried to access the a variable from console and I couldn't. So I wanted to know - will users be able to access those variables and change them if I use this kind of structure?
There is nothing you can to do completely secure that variable. Users will still be able to access it using the debugger, local overrides, or probably other means as well.
A value like that which you need to be immutable to a skilled browser user needs to be stored on a secured backend (server, api, or something).
For example see:
Is there a way to change variable values while debugging JavaScript?
Related
Recently I started developing some extensions for Chrome. I am doing this in manifest v3 and vanilla javascript. I have managed to make my extensions work. However, part of the fun of creating them is in learning to code better. I have been wondering whether I am handling variables in a correct way.
I have some data that I like to access from various points in my extension. Some of it is loaded dynamically and some I set in the code directly, like this:
const myExtensionData = {
someData: [],
config: [],
links: [],
}
1) Is it a good idea to store often-used data in a variable like myExtensionData.someData? Is there a better alternative?
myExtensionData.someData is loaded from externally at some point in time. As I use this data in various functions, I have exposed it like this, so that I don't have to pass the data every time. I could use the local storage, but I have been holding that back as that requires another permission.
2) Same question, but this time with stuff that is rarely used (myExtensionData.config)?
The data in myExtensionData.config is also created dynamically, but the contents are not used as much. For example: I store whether one of my other extensions is also installed. If it is, I enable a button to access it from the popup. Rather single-use.
3) How about static variables? (myExtensionData.links)?
I keep some links I use for onUpdate, onInstall and for release notes. They change regularly, so I needed to store them somewhere. How about storing them in myExtensionData (I actually keep them in a global const at the moment).
4) Any pointers are appreciated!
I hope this is a worthy question. It's not very specific at all, but I am sure I can learn a lot here. I have searched for good practices/best practices, but they are usually outside the context of extension. If I have been looking at all the wrong places, please let me know.
Trying to answer my own question
I found some interesting stuff in this very old question. As I understand it, it's not a bad thing to store a variable in an object. Additionally, I like that it is also suggested to add some methods to the object as well.
I'm using a query on both server and client (pub/sub). So I have something like this at a few different locations.
const FOO = 'bar';
Collection.find({property:FOO})
Foo may potentially change and rather than have to update my code at separate locations, I was thinking it may be worth it to abstract this away to a global variable that is visible by both client and server.
I created a new file 'lib/constants.js' and simply did FOO = 'bar; (note no keyword). This seems to work just fine. I found this solution as the accepted answer How can I access constants in the lib/constants.js file in Meteor?
My question is if this a desired pattern in Meteor and even general JS.
I understand I can abstract this away into a module, but that may be overkill in this case. I also think using session/reactive vars is unsafe as it can kinda lead to action at a distance. I'm not even gonna consider using settings.json as that should only be for environment variables.
Any insights?
yes, If you are using older version of meteor then you can use setting.json but for updated version we have import option.
I don't think the pattern is that bad. I would put that file in /imports though and explicitly import it.
Alternatively, you can write into Meteor.settings.public from the server, e.g., on start-up, and those values will be available on the client in the same location. You can do this without having a settings file, which is nice because it doesn't require you to make any changes between development and production.
Server:
Meteor.startup(() => {
// code to run on server at startup
Meteor.settings.public.FOO = 'bar';
});
Client:
> console.log(Meteor.settings.public.FOO);
bar
This is actually a b̶a̶d̶ unfavoured pattern because with global variables you cannot track what things changed and in general constructing a modular and replaceable components is much better. This pattern was only made possible due to Meteor early days where imports directory/pattern was not supported yet and you'd have your entire code split up between both,server and client.
https://docs.meteor.com/changelog.html#v13220160415
You can find many write ups about it online and event stackoverflow answers so I don't want to restate the obvious.
Using a settings.json variable is not an option since we may dynamically change so what are our options? For me I'd say:
Store it the database and either publish it or retrieve it using methods with proper access scoping of course. Also you can dynamically modify it using methods that author DB changes.
Or, you may try using Meteor.EnvironmentVariable. I'd be lying if I said I know how to use it properly but I've seen it being used in couple Meteor projects to tackle a similar situation.
https://www.eventedmind.com/items/meteor-dynamic-scoping-with-environment-variables
Why are global variables considered bad practice?
I would like to save a "snapshot" of a webpage which however should remain in an "interactive" state -> all Javascript state has to be saved and restored.
Example showing the issue I'm trying to solve: Given a webpage which executes the following script in the global scope:
function f(x) { return function() { return x; } }
var g = f(2);
I'd like to save both the function f (more or less trivial) and the variable g (which closes over x from the f invocation) to a file and restore the state of the website later.
As far as I could figure out it seems to be impossible to do this using only "web" technologies (ie. with the permissions the webpage itself has). I'm therefore guessing I'll have to implement a browser addon to achieve this.
Does something like this already exist? What would be a good starting point? I noticed that Firefox Session Restore does something similar, do you know if I could reuse this mechanism? If not would it be feasible to implement something like this as a "debugger" style addon? Are there simpler solutions?
Javascript objects hold onto DOM/other native objects. Native objects have hidden state and can be entangled with global browser state or addons.
So the only real way I can think of is to run a browser in a VM and snapshot/clone that VM.
It seems there's no way to completely hide source/encrypt something to prevent users from inspecting the logic behind a script.
Aside from viewing the source, then, is it possible to manipulate every variables, objects while a script is running?
It seems it is possible to some degree: by using Chrome's developer tools or Firebug, you can easily edit variables or even invoke functions on the global scope.
Then what about variables, functions inside of an instantiated objects or self invoked anonymous functions? Here is an example:
var varInGlobal = 'On the global scope: easily editable';
function CustomConstructor()
{
this.exposedProperty = 'Once instantiated, can be easily manipulated too.';
this.func1 = function(){return func1InConstructor();}
var var1InConstructor = 'Can be retrived by invoking func1 from an instantiated object';
// Can it be assigned a new value after this is instantiated?
function func1InConstructor()
{
return var1InConstructor;
}
}
var customObject = new CustomConstructor();
After this is ran on a browser:
// CONSOLE WINDOW
varInGlobal = 'A piece of cake!';
customObject.exposedProperty = 'Has new value now!';
customObject.var1InConstructor; // undefined: the variable can't be access this way
customObject.func1(); // This is the correct way
At this stage, is it possible for a user to edit the variable "var1InConstructor" in customObject?
Here's another example:
There is a RPG game built on Javascript. The hero in the game has two stats: strength and agility. the character's final damage is calculated by combining these two stats. It is clear that players can find out this logic by inspecting the source.
Let's assume the entire script is self invoked and stats/calculate functions are inside of objects' constructors so they can't be reached by normally after instantiated. My question is, can the players edit the character's str and agi while the game is running(by using Firebug or whatever) so they can steamroll everything and ruin the game?
The variable var1InConstructor cannot be re-bound under normal ECMAScript rules as it is visible only within the lexical scope. However, as alex (and others) rightly say, the client should not be trusted.
Here are some ways the user can exploit the assumption that the variable is read-only:
Use a JavaScript debugger (e.g. FireBug) and re-assign the variable while stopped at a breakpoint within the applicable scope.
Copy and paste the original source code, but add a setter with access to the variable. The user could even copy the entire program invalidating almost every assumption about execution.
Modify or inject a value at a usage site: an exploitation might be possible without ever actually updating the original variable (e.g. player.power = function () { return "godlike" }).
In the end, with a client-side program, there is no way to absolutely prevent a user from cheating without a centralized authority (read: server) auditing every action - and even then it still might be possible to cheat by reading additional game state, such as enemy positions.
JavaScript, being easy to read, edit, and execute dynamically is even easier to hack/fiddle with than a compiled application. Obfuscation is possible but, if someone wants to cheat, they will.
I don't think this constitutes an answer, it could be seen as anecdotal, but it's a bit long for a comment.
Everything you do when it comes to the integrity of your coding on this issue has to revolve around needing to verify that the data hasn't changed outside of the logic of your game.
My experience with game development (via flash, primarily...but could be compared to javascript) is that you need to think about everything being a handshake where possible. When you are expecting data to come to the server from the client you want to make sure that you have some form of passage of communication that lessens the chance of someone simply sending false data. Store data on the server side as much as possible and use the client side code to call for it when it's needed, and refresh this data store often.
You'll find that HTML games tend to do a lot of abstraction of the logic to the server side, even for menial tasks. Attacking an enemy, picking up an item, these are calls to functions within server-side code, and is why the game animation could carry on in some of these games while the connection times out in the background, causing error messages to pop up and refresh the interface to the server's last known valid state.
Flash was easier in this regard as you didn't have any access to alter any data or corrupt it unless it left the flash environment
Yes, anything ran on the client should be untrusted if you're using the data from it to update a server side state.
As you suggested, you can't hide the logic/client-side code. You can make it "harder" for people to read the source by obfuscating it, but it's very trivial to undo.
Assuming you're making a game from your example, the first rule of networked games is "never trust the client". You need to either run all the game logic on a server, or you need to validate all the input on a server. Never update the game state based on input from a client without validating it first.
You can't hide any variable.
Also, if the user is so good in javascript, he can easily edit your script, without editing the variables value through the console.
JS code that is injected into an HTML using Ajax is pretty darn difficult to get your hands on, but it also has it's limitations. Most notably, you can't use JS includes in injected HTML . . . only inline JS.
I've been working with some of that recently actually and it's a real pain to debug. You can't see it, step into it, or add breakpoints to it in any way that I can figure out . . . in Firebug or Chrome's built-in tool.
But, as others have said . . . I still wouldn't consider it trusted.
I wrote a server-client app in javascript/HTML5 its supposed to allow clients to communicate/play a game in realtime using Node.js on the server side .
I know the use of private variables and etc . But how to prevent the whole game engine from unauthorised access via console api ?
As in how to write it in such a way that all variables fall in a private scope and once initiated they run pretty much independently without registering a single variable in the global scope so that nobody can mess the Game up!
From what i have researched i can do something like
function Game(){
// All declarations here
// Start a logic in here
}
and then calling it
new Game();
will do it ? but is there any better way to do the same ?
You can run a JavaScript application without registering any single variable, via an anonymous function:
(function() {
//local variables here.
})();
However, there is no reliable way to prevent cheating: One can easily analyse your code, and create fake AJAX requests. With the latest browsers, it's incredibly easy to capture your code.
With getters and setters, anyone can effectively intercept your functions. Using the deprecated arguments.callee.caller property, an attacker can read the source of the function call, effectively getting access to the closure as defined at the top of this answer.
Example:
var _alert = alert;
window.alert = null;
Object.defineProperty(window, 'alert', {
'value': function(m) {
console.log('Intercepted. Function source: ' + arguments.callee.caller);
_alert.call(this, m);
}
});
(function(){
var localVar = 'secret';
alert('Hi!');
})();
You can't trust anything that runs on the client's hardware, and that it. Even with the example you've given, anyone could easily modify and reload your script to cheat. Your best bet here, then is not to put any extra effort into this, but rather by writing your application normally and running it through a preprocessor like UglifyJS. The anonymous function pattern indicated by Rob in his answer is also common.
Also, about the MD5 hash thing - no, even if it's in "private scope" you can still view and modify it in a JavaScript debugger. The point here is that someone will always cheat because of the entire nature of the JavaScript execution environment - it's just that you'll need to make it as difficult as possible to cheat by obfuscating your code (obviously using a preprocessor) and other similar techniques.
JS code is always available, you may want to obfuscate your code to make cheating harder
All security can be circumvented with enough time. The goal of every security measure is to increase the time it takes to crack What Rob W says will help, but I suggest you also invest in obfuscation/minimization of your javascript which will have a much greater impact on the time and effort required to analyze it and create fake ajax requests than avoiding global variables.
However I concur that a javascript based application can never be very secure. The best you can hope for is "annoying to hack"
How can I obfuscate (protect) JavaScript?