0

NOTE: This is my first post, so please tell me if there is anything I should do better in that respect

I am making a javascript game (node as server, browser as client) in which the users can provide a string of a function to be executed as the AI of their troops. I am trying to securely let them run their AI functions on the server (strings are passed from client to server, and run on the node.js server for their troops AI). I am using a function constructor to specify precisely which objects and functions they are allowed to access. The objects that are passed to their functions are clones of the real ones and can only be used for reference (stats,positions of troops,health,etc.).

My problem comes from the fact that they have to give commands to the game, so I need some way of passing in (or allowing some sort of access) to certain functions that i have made. For example I have a move(int,int){} function that will move the troop by the values it is passed (the user will not have access to this). I also have a safeMove(int,int){} function (this function is attached to the troop object that I want them to safely control) that is passed to the user's AI function. The safeMove will take the inputs, and once the safeMove function has verified the inputs as valid, it will call move() with the verified params.

I don't want the user to have access to the troop object or they could change things i didn't want them to (example: give their troop a ton of health). The problem I am having is that when I pass the safeMove function it references this.move(). Because this no longer refers to what it used to, it no longer has access to the move function.

How should I enable the user to have access to functions (or some filtered pass-thru) that tell the object what to do, without giving them access to actually change anything?

Security isn't an actual problem since this game will most likely be just for me and my friends, but I still want the learning experience, and to make sure my friends don't cheat :)

edit: Here is a code example that shows my problem.

var objectIDontWantUserToAccess = {}  
objectIDontWantUserToAccess.move = function(int1,int2){
     ... //I don't want user to access this function  
};
objectIDontWantUserToAccess.safeMove = function(int1,int2){
    if(int1 is considered valid and int2 is considered valid){
        this.move(int1,int2)
    }
}
var userFunction = new Function("safeMoveFunction",textOfUserDefinedFunction);  
// the user defined function can call safeMoveFunction(int,int) since it was passed to it.
userFunction(objectIDontWantUserToAccess.safeMove());
// userFunction can access the safeMove, but when it calls this.move() 
// this will no longer refer to objectIDontWantUserToAccess.  

Am I going about this the wrong way, or is there no way to be able to run a user defined function without giving them access to the object that they need to edit.

trincot
  • 317,000
  • 35
  • 244
  • 286
Donut
  • 59
  • 1
  • 7
  • welcome to sackoverflow Please read these posts first. https://meta.stackexchange.com/help/how-to-ask https://meta.stackoverflow.com/questions/251361/how-do-i-format-my-code-blocks – isuruAb Mar 18 '17 at 03:47
  • Post some code you have so far to make your point clear – bibek shrestha Mar 18 '17 at 05:56
  • I have added a code example. Does this show my problem well enough. I could be trying to solve this in an entirely wrong way, so if there is a completely different way to solve this problem, please tell me. – Donut Mar 18 '17 at 23:06
  • "*users can provide a string of an AI function to be securely run on the server*" - this is doomed to fail. Sandboxing untrusted code is *hard*, don't try to reinvent the wheel. Scoping rules are certainly not enough. Either come up with your own, secure AI language and write a (bug-free) interpreter for that, or use an existing sandboxing solution where you execute the code in its own process in a virtual machine. – Bergi Mar 18 '17 at 23:41
  • Regarding your issue with `safeMove`, see [How to access the correct `this` inside a callback?](http://stackoverflow.com/q/20279484/1048572) – Bergi Mar 18 '17 at 23:43
  • @Bergi I realize that you can't be fool proof with filtering, but I am only going to use this for a learning experience, and for playing this game with my friends. Because of that, I only want to make it very difficult to break. I understand the dangers of running someone else's code. – Donut Mar 19 '17 at 00:07
  • @Bergi I am currently trying out your suggested solution. I will update this comment when I see if that works for me. Thank you. – Donut Mar 19 '17 at 00:08
  • @Bergi Thank you for your comment regarding proper "this" use. That ended up solving my problem. Because I am such a low level stackoverflow user, I don't believe I have the rights to approve your comment as the answer, or up-vote it either. Is someone else able to? – Donut Mar 19 '17 at 01:09
  • No, it's just because it's a comment and not posted as an answer. I can close the question though if that other question solved your problem – Bergi Mar 19 '17 at 09:52

0 Answers0