A report from a newbie web programmer

I have been recently trying to understand how multiplayer online worlds work, from the basic technical matters, to higher level game mechanics. This is a new area for me, and seems a bit of a black art so I thought I’d write some of the things I’ve discovered here for others following a similar path, or more likely, so people can tell me where I’m heading in the wrong direction.

I had to start with the complete and utter basics (as a recovering computer graphics guy) and to start with these games are split between a client and a server. The clients I’m interested in run in players browsers, and the server needs to be on a machine which is running all the time to provide the persistent world, and record the changes people make.

In terms of languages, when considering the client you are quite restricted as to what you can use. Every browser has a Javascript interpreter, and most people have flash – sidestepping the hot potato I’ve already written a bit about. Luckily for flash there is also haxe.

On the server it’s completely up to you what you use, as you can run pretty much anything in a webserver. I’m using a racket servlets so I can use Scheme.

Sending requests from the client to the server

In a game the client needs to issue requests to the server while the game is running, in order to get realtime feedback on what is going on. As far as a browser is concerned, it does this first to get the page, but as we also need a way to do this after the page has loaded. This technique is usually called AJAX, or “Asynchronous JavaScript and XML” and was a hot topic a few years ago due to the rise of Google maps and other websites that make heavy use of it. All it really means is that you can send a http request from a script running on a page, and get a result from the server. I’m skipping the XML part, but I think it’s the same idea.

In JavaScript you can do this with the popular jquery library, where a request looks something like this:

$.get("page.html", {argument1: 302, argument2: "hello"}, function(data) { do_something_with(data); } );

The page and arguments will result in a call to a url like this:

http://your-site.com/page.html?argument1=302&argument2=hello

When it’s returned, the result data will be passed to the function you pass in as the third argument. Notice that this function will be called “at some time in the future” – as it’s asynchronous. This means your script can do other things while it’s waiting for the data.

In Haxe you need to use a combination of things to do the same work:

// setup the loader
var Loader:URLLoader = new URLLoader();
Loader.addEventListener(Event.COMPLETE, CompleteHandler);
...
// define the callback for when the request has finished
function CompleteHandler(event:Event)
{
    DoSomethingWith(Loader.data);   
}
...
// set off the request
var request:URLRequest = new URLRequest("page.html?argument1=302&argument2=hello");
Loader.load(request);

Although I’m stuffing the parameters on the the url string myself, there is a URLVariables object which is supposed to do this cleanly – but I couldn’t get it to work.

Security issues

One thing you might notice is that we don’t specify the root of the url anywhere in the code, and this is for a very specific reason. The client code is restricted to only sending requests to the server which has served the page itself. This makes it hard to run a client from a location not controlled by the same people as the server – if this were possible, for example, a third party would be able to write a client that acted like the real one, but used your identity to do whatever it wanted. This is called the same origin policy.

A related issue crops up if it is possible for people to enter text which gets shown in the webpage of the game on other people’s computers. The problem here is that it may be possible for a third party to inject some code that gets executed into the website that gets sent to a player. This could result in all sorts of mayhem, for example inserting dialogs that look like they come from your website to extract personal information. This is called cross-site scripting (shortened to xss). There is no utterly foolproof way of preventing this, but a simple approach is to filter out special characters (such as angle brackets) from the input from your game as they come in to the server.

A third issue for security is to be careful of what you do with the requests you get – as while the users are protected from being tricked into running an altered client that looks like it comes from you, your server can still have requests sent to it from anyone.

For instance, it would be the easiest thing in the world to design an elegant and simple interface that directly ran code being sent to a server – eg a request such as:

http://mysite.com/myserver?func=display¶m=hello

Could easily, even indirectly be run by some code like this:

(apply func (list param))

Which immediately opens your server up to people sending it calls such as

http://mysite.com/myserver?func=delete-file¶m=server.scm

And presumably much worse.

So it’s important to use some indirection to verify that the commands you are being sent make sense, and come from a limited range of options controlled by you. Related to this, if you have command that create new objects somehow – it’s a good idea to have some limits imposed, to prevent some troublemaker writing a script that fills up the memory on your server.

Sending data from the server to the client

The data you send back as a result of requests can be of any form, but there are some useful standards here. I’ve chosen to use JSON which is another web programming four letter acronym that stands for JavaScript Object Notation. We saw a Javascript object earlier on, as part of the request being sent out, but they are just associative arrays. Here is another example that might come back from the server:

{
    player-id: 43,
    text: "destroy all humans",
    numbers: [3, 42, 32, 4, 1]
}

This can then be evaluated by the client and turned into an object that can be inspected by the game.

There is a risk from directly running eval on the text that comes from the server – as potentially this too could somehow be subverted to contain some executable data, although this is quite unlikely, it’s best to filter the text. Luckily there are lots of libraries to do this – I’ve used json2 before discovering that jquery has a getJSON call that does this for you.

3 thoughts on “A report from a newbie web programmer

  1. It looks to me like you are only looking at security in terms of issues any website could have; fishing, injected ads, etc. I think with games there are different kinds of incentive (cheating) and those may well cause different security concerns.

    I might -for example- spoof your site to make Alex send his turns to my fake site, leading to a time-out on your server for our game of chess, making me the winner. This is different from spoofing a bank website in that I wouldn’t care about the content of the data that Alex sends, as long as he has the feeling he is sending it to you.

    You may also need some method to verify the client or to make sure there is no benefit to a modded/ patched client. For example; a random function to determine whether I get a “rock” or a “Ring of Spell Casting +20” should probably not run on the client-side.

    I think this is important, the fun of competitive games is founded on the perceived fairness of the system. If Nick beats me by a order of magnitude in points I could either practice harder or call him a cheater, then leave.

    Some of these attacks are realistic (comparing benefits to effort), others likely less so. We saw people cheat at Bejeweled on FB to get highscores amongst their friends (see various Youtube vids), I don’t think anyone tried to spoof FB to keep a single friend from ranking in.

  2. Yes, at the moment I’m really just concerned that no real damage can be done by running web apps I make, and that I understand what the factors are.

    Cheating is a different matter, and I guess I was thinking along the lines of the client being moderately thin in order to keep as much of the game logic as possible in the server, as you say.

    On the other hand, these projects are not commercial products, so I would consider an explosion of modified clients and some aspects of cheating to be highly desirable – but the distinction between creative manipulation and annoying activity often depends on your viewpoint, so this could be an interesting problem to take on :)

  3. I believe that in competitive play any moves that are “within the system” are typically deemed “fair”. That needn’t mean they were put there on purpose (like “roll cancels” in Capcom v.s. SNK2 which can make normal moves invulnerable and are a hard to perform glitch). It also means that not nearly every game intended for that sort of playing is suitable for it in the long term.

    I think that what you are going for is quite unlike the games aimed at the (Japanese) arcade tournament scene but perhaps there is inspiration here. These have large and complicated systems, and aside from dexterity getting to know the system of the game is essential to high-level play. This isn’t unlike our kind of “game” here, I think, in that sense. Arcade games have very clear “borders of the system” in the form of cabinets aimed at public installation that can take a beating. I’d look at a clear way of defining the borders of the system for your game, this might interact with traditional security. It would also imply that there be no real way for the game itself to interact with the borders (or that such ways be removed).

    Here is a example of such a thing; http://www.youtube.com/watch?v=VSBjqSV40Uw That’s a move within the system that interact with it’s borders (player2’s input) and back when this game was played doing this was banned in tournament play, though being able to do it was seen as a accomplishment. Capcom, of course, fixed it with the next update, which -interestingly- also adopted many moves introduced by mods to the source of illegal mods.

    “Our kind of game” (corewars, Nomic, etc) might be about exploring the rules and exploring what’s possible within them too. This may well lead to things many people would call “cheating” and that we would call very imaginative, praise-worthy and cause for a update. Typically things are only “clever” the first time they are done. It might sound boringly conservative but I’d say that that would also imply a need for especially clear borders of the system. I don’t think that the non-commercial nature matters all that much for this, to me this is more about the gut-feeling that making sure everybody plays the same game will lead to more fun. This could lead to excitement when another player shows us a new side to the game, something I don’t think Alex would feel in the chess example above.

    Perhaps this sounded too abstract, or too obvious? I think that the way we secure something should be affected from the ground up by what we are trying to secure. We wouldn’t want to do the equivalent of raising a child too protectively or putting laws in our books against wild raindeer copulating on the public road (I heard that last one actually happened, might be a myth). This might -of course- be a iterative process.

Leave a Reply

Your email address will not be published. Required fields are marked *