Table of Contents
Any MMOG needs to implement robust solutions to safeguard its environment from exploits. This chapter describes the measures adopted by BigWorld to provide safety for your data.
The list below describes the measures taken to guarantee the security of client/server communications:
-
Security measure: Login authentication
Opportunity thwarted: Unknown user using a player's account.
When a player logs in to a BigWorld server, he sends a username and a password. These are compared to a server-side database, to make sure that the user is subscribed.
The source code is available to the login procedure, so this method can be customised as desired.
-
Security measure: Packet authentication
Opportunity thwarted: Player pretending to be someone else, by spoofing another player's data.
When a player logs in to a BigWorld server, the server sends a 32-bit session key back to the client. The client must use this key in all further packets sent to the server, or the packet will be rejected.
Optionally, the server can also send to the client an authentication key with every packet. This makes it very hard for an attacker to successfully masquerade as the server.
Also, every command called on the server has the client's ID added to the arguments. This is done by the BaseApp before the command is transmitted, so the client cannot fake the ID.
-
Security measure: Encryption
Opportunity thwarted: Attacker sniffing data to gain privileged information, or injecting new packets into client-server streams.
All traffic between the client and server is encrypted. The credentials sent to the server during login are RSA-encrypted and all client-server traffic after this point is encrypted with 128-bit modal Blowfish. This makes it very difficult for an attacker to inject new packets into either the upstream or downstream traffic; without knowing the Blowfish key, the probability of generating a packet that will parse correctly and not be discarded is extremely low.
It would still be possible for a player to hack its own binary and sniff the data stream from the server after it has been decrypted.
-
Security measure: Data hiding
Opportunity thwarted: Player accessing privileged information.
All properties of entities are tagged with propagation specifiers. These allow the server to control where information is sent.
For example, you may want to hide the actual health of NPC players, to prevent players from cheating by sniffing the data stream.
This is a common problem on MMOGs that receive data that is not always displayed to the user.
For more details, see Data Distribution.
-
Security measure: Sequence numbers
Opportunity thwarted: User spoofing and replaying captured stream.
All packets are stamped with a sequence number, and packets are rejected if the sequence number is repeated.
This makes it much harder for a hacker to capture a data stream and replay it, or inject packets to fake game operations.
-
Security measure: IP address masking
Opportunity thwarted: User doing DOS attacks on clients.
A player's IP address is not shared between clients, making it impossible for hackers to sniff it and then perform a Denial Of Service attack on that client.
-
Security measure: Privilege checks on RPCs
Opportunity thwarted: Player calling server-only functions.
Both client and server entities call functions (Remote Procedure Calls) on Python objects.
The developer tags all methods with accessibility flags. This enables the server to check all calls to make sure that they are legal.
Security for the internal server-side network is provided by a simple proxy mechanism ‐ the only machines exposed to the Internet are the LoginApps and BaseApps (for more details, see the document Server Overviews section Server Components → BaseApp).
As such, internal server traffic between BigWorld components (e.g., CellApp to BaseApp traffic, CellApp to CellAppMgr traffic) cannot be sniffed.
Additionally, each server component is only required to listen for all external communications on a single UDP port. This way, all other network services can be disabled, including TCP, which is the target of many known attacks. Listening on a single UDP port for communications with all clients (as opposed to a distinct port for each) also has the following advantages:
-
It becomes impossible for one client to guess another's port, and thereby impersonate it.
-
A single recv() is used for all incoming messages on the server side, instead of a select() across a large number of per-player sockets. This results in a more efficient message handling implementation.
The list below describes the measures taken to guarantee the security of the client side:
-
Security measure: CD Key
Opportunity thwarted: Stealing of CD images
BigWorld Technology does not cover distribution issues.
But since an MMOG client must connect to a server to play the game, this problem can be solved by modifying the login process so that, in addition to the username and password, the CD key is also sent to the server and checked against a database.
As a developer, you need to watch out for hacked clients, and third party apps (often called 'trainers'). It is also important to realise that it is very hard to prevent all forms of cheating. You should decide what forms of cheating will impact you and/or your customers, and work on those issues, and do not let minor cheating distract you.
The most important rule is to always be careful with data sent from the client. If possible, everything that the client does should be checked for validity on the server. Simple rules, like ensuring that a switch can only be activated when the player is close enough to throw the lever, are easy to enforce. To simplify these checks, an extra 'source' argument is added to the parameter list for every method exposed to the client. The client does not send it up ‐ it is added by the BaseApp automatically. Also, to make it harder for clients to cheat, methods not exposed to the client are excised from the address space that it sees.
Generalised physics checking on more frequent interactions, such as movement, is not so easy, since running the physics of every player on the server would be quite expensive. One solution is to use the high-level geometry of the world as the expression of the important physical rules. The world is built up of polyhedral chunks connected by portals. A chunk equates to one room in inside areas. Whenever the player moves between chunks, we check that the movement passes through a portal, and that the player has not moved too fast. This means that we are not concerned about petty violations of physical rules, like standing in the middle of a table, but we do catch violations that influence the game, like moving through walls or locked doors, and moving too quickly.
The general rule is to send data to the client only if it is necessary. This saves bandwidth, as well as helping reduce hacking. There are three techniques you can use with BigWorld Technology:
-
Level of Detail
Instead of constantly sending entity information, you might want to send it only when it is within range. For example, a player might be able to see a monster from 500 metres away, but its level does not have to be sent to the client until it is within 20 metres.
-
Data hiding
Some information should never be sent to the client. For example, NPC health could be kept local to the server, and the client can just call functions that affect it (e.g., doDamage(10)). The server sends the results to the client (e.g., monster limping because health is below 50%).
-
Data on request
The client should call server functions to request data only when needed. For example, your game could be designed such that the client must physically 'con' a monster by calling a server-side function that returns level and health. To detect potential cheating the server could then flag clients that con more than one monster per second, or con monsters further than 20 metres away.
As mentioned in other places, the responsibility for security in a
BigWorld-based game is shared between the engine itself and the game
script running on top of it. In particular, script writers must be very
careful in the design and implementation of
<Exposed/>
methods. Please see Exposed Methods ‐
Client-to-Server Communication for more details on the specifics of
the security requirements for exposed methods.
Note
Please be aware that at this point in time, the FantasyDemo game that ships with each BigWorld package has not been bulletproofed against the actions of malicious clients and in all likelihood contains security vulnerabilities in its exposed methods. We are working on improving this and offering a FantasyDemo to customers that serves as both a good feature demonstration as well as a good example of secure script.
As much as security is important, as a developer you have to be careful so that it does not impact too much the player's experience of the game.
The game has to be responsive, but the game play may feel very lagged if the client passed all movement and combat commands to the server for validation before showing results. Therefore, you are best off handling movement on the client side, or simultaneously on the client and the server. For example, to have a fast-paced shooting game, you would need to perform client-side tests for impact, and show the result immediately (monster recoils when hit, etc...). Simultaneously, you would send the shoot command to the server, and let the server send down any changes of health if the monster is really hit. This means that the client cannot cheat with shooting, but still gets lag-free results.
This is one of the biggest issues in controlling hacking. For example, it may be too expensive to check all player physics on the server. The developer has to pick the most common forms of cheating, and check for those.
It is sensible to allow checks to be turned on and off per player, or only check 10% of the players at any one time. Statistical checking can be useful, for example by monitoring how many XP are gained over time by players, to check if they are accumulating points at an unfeasible rate. If the player becomes a suspect of cheating, then more checks can be turned on for him.