Multiplayer Game Programming: Architecting Networked Games (2016)
Chapter 10. Security
Since the first networked games, players have devised ways to gain an unfair advantage. As networked games have become increasingly popular, combating security vulnerabilities has become an important part of providing a safe and fun environment for all players. This chapter takes a look at some of the most common vulnerabilities and the preventative measures that can be taken against them.
In normal network operation, packets are routed through several different computers on their path from the source to destination IP address. At the very least, the routers along the way need to read the header information in the packets in order to determine where to send the packet. And as covered in Chapter 2, sometimes the header addresses may be rewritten for network address translation. However, given the open nature of the data that is transmitted, there is nothing that prevents any of the machines on the route from inspecting all of the data in a particular packet.
Sometimes inspecting the payload contained in a packet might be done in the name of normal network operation. For example, some consumer routers employ deep packet inspection in order to implement quality of service—a system that prioritizes some packets over others. Quality of service needs to read the packets to determine what it contains. This way, if a packet can be determined to contain peer-to-peer file sharing data, it may be given a lower priority than a packet containing data for a voice-over IP (VoIP) call.
But there also is a form of inspecting these packets that is not necessarily as benign. Packet sniffing is a term generally used for the reading of packet data for a purpose other than normal network operation. This can be done for many different purposes including attempting to steal login information or cheating in networked games. The remainder of this section focuses on the specific ways various types of packet sniffing can be combatted in networked games.
In a man-in-the-middle attack, a computer somewhere on the route from source to destination is sniffing packets, without the knowledge of the source and destination computers. This is shown in Figure 10.1. Practically speaking, there are a few different ways this can occur. Any computer using an unsecured or public Wi-Fi network could have all of its packet information read by another machine on that network. (This is why it is generally a good idea to use an encrypted VPN when on a Wi-Fi network at the local coffee shop). If on a wired network, it could be that a gateway machine is sniffing packets—either because of some sort of malware, or due to a nosy system administrator. And if, for some reason, government agents are targeting your game, it is also possible that software installed at an ISP is attempting to gain access to the data.
Figure 10.1 A man-in-the-middle attack, with a message between Alice and Bob being read by Clive
Technically, a player could intentionally set up a man-in-the-middle for the purposes of sniffing the game. This may be a concern on a closed platform such as a console, but at least on PC or Mac, you should assume that the player always has access to all of the data transmitted over the network, anyway. So for the rest of this discussion of man-in-the-middle, we will assume that the “man” is a third party unknown to both the source and destination computer.
The general approach to combatting the man-in-the-middle is to encrypt all transmitted data. In the case of a networked game, prior to implementing any sort of encryption system, one should consider whether the game in question contains any sensitive data that needs to be encrypted. If your game contains any microtransactions where a player can purchase in-game items, it absolutely needs to encrypt any data related to purchases. If you are storing or even just processing credit card information, the Payment Card Industry Data Security Standard (PCI DSS) may be a legal requirement. However, even if there are no in-game purchases, any game where a player logs in to an account that saves progress, such as a MOBA or MMO, should encrypt data related to the login process. In both of these cases, there is a monetary incentive for a third party to steal information—whether credit card or login. So it is imperative that your game protects player’s valuable data from a man-in-the-middle.
On the other hand, if the only data your game transmits over the network is replication data (or the like), it doesn’t really matter if the man-in-the-middle intercepts this data. Thus, you could leave the data unencrypted and it wouldn’t be a big issue. That being said, there may still be some value in encrypting the data to prevent host packet sniffing, which is discussed shortly.
If you come to the conclusion that your game does send sensitive data that needs to be protected from outside parties, then using a proven encryption system is the recommended course of action. Specifically, you will want to use public key cryptography, a type of cryptography well suited for transmitting secure information. Suppose that Alice and Bob want to transmit encrypted messages to each other. First, before they begin talking to each other, Alice and Bob both generate different private and public keys. The private keys remain private to whoever generated the key—they should never be shared with anyone else. When Alice and Bob first handshake with each other, they will exchange their public keys. Then when Alice sends a message to Bob, she will encrypt the message using Bob’s public key. This message can then only be decrypted using Bob’s private key. In essence, this means that Alice can send messages to Bob that only he can read, and Bob can send messages to Alice that only she can read. This is the essence of public key cryptography, and is illustrated in Figure 10.2.
Figure 10.2 Alice and Bob communicate via public key cryptography
In the case of a networked game where there’s a login server, the client would have access to the server’s public key. When the client wishes to log in to the server, their login and password are encrypted using the server’s public key. This login packet can then only be decrypted by the server’s private key, which hopefully only the server knows!
Arguably the most popular public key cryptography system in use today is the RSA system designed in 1977 by Rivest, Shamir, and Adelman. In RSA, the public key is based on a very large number that is a semiprime, meaning it is the product of two prime numbers. The private key is then based on the prime number factorization of the semiprime. The system works because no known polynomial-time algorithm exists for integer factorization, and brute-forcing the factorization of a 1024- or 2048-bit number that is the product of two large prime numbers, at this time, is likely impossible even on the most powerful supercomputer in the world.
There are a few scenarios where RSA could be broken, and any of these would be disastrous in the near-term. The first scenario would be the creation of a sufficiently powerful quantum computer. Shor’s algorithm is a quantum computer algorithm that can factor integers in quantum polynomial time. However, at time of writing, the most powerful quantum computer in the world can only handle factorization of 21 into 7 and 3, so it may be a few years before a quantum computer factors a 1024-bit number. The other scenario is that a polynomial-time algorithm for integer factorization for standard computers is devised.
The reason why this would be disastrous is because a great deal of secure communication on the Internet relies on RSA or related algorithms. If RSA is broken, this means that many keys used for HTTPS, SSH, and similar protocols would no longer be secure. Most cryptographers are resigned to the fact that RSA will eventually be broken, which is why there is active cryptography research today on systems that even a quantum computer would not be able to solve in polynomial time.
Since RSA is such a well-established cryptography system, it would be a waste of resources to attempt to implement it on your own. Instead, use a trusted open-source implementation of RSA such as the implementation provided in OpenSSL. Because OpenSSL is released under a free software license, even commercial projects should have no issue with using it.
Packet Sniffing on a Host Machine
While only games that transmit sensitive data need to worry about a man-in-the-middle attack, every networked game is susceptible to a host machine intentionally sniffing packets. In this case, encrypting the data is a deterrent but is not a foolproof measure. The reason for this is a game executable on any platform can always be hacked, so encrypting the game data won’t prevent someone from learning how to decrypt the data. Somewhere, there must be code within the executable that knows how to decrypt the data the executable is to receive. Once the decryption scheme is determined, the packet data can be read as if it weren’t encrypted.
That being said, reverse engineering the decryption code and finding the private key stored in the client does take some time. So one way to make it more difficult for potential cheaters is to still encrypt the data, but change the encryption keys and memory offsets to those keys on a regular basis. This will then require someone to repeat the reverse engineering process every time your game is updated. Similarly, if your game changes the format and ordering of packets on a regular basis, this renders cheats that rely on a specific-packet format obsolete. Once again, this makes players spend time to learn the new format and get the cheats to work again. So, changing the encryption or packet format regularly will make developing cheats for your game more annoying. Hopefully, this means most players give up in developing cheats. But either way, you still have to accept the fact that you will never be able to prevent dedicated individuals from sniffing all of the packets on a host machine.
It’s worthwhile to consider what exactly a player packet sniffing on the host machine seeks to accomplish. The player on the host machine is generally trying to utilize an information cheat, meaning he or she is trying to glean information that he or she should not know. A common refrain to prevent cheating in this case is to limit the amount of information transmitted to each host. In a client-server game, it is very much possible for the server to limit the data it sends to each client. For example, suppose a networked game supports players moving undetected in stealth mode. If the server still sends replication updates on a character in stealth, then a player could absolutely glean the position of these stealth players from the packets. On the other hand, if replication updates for position pause while a character is in stealth, there will be no way for the client to know the current position of the character.
In general, you should assume any data sent to each host can be examined by a player trying to cheat. Thus if the game ensures that only the critical information relevant to each host is transmitted, then it will minimize the potential for cheating. This will be much easier to enforce in a client-server topology than on a peer-to-peer topology, since peer-to-peer can only work if all data relevant to the game is sent to every peer. Thus a peer-to-peer game needs to use other approaches to combat cheating.
In contrast to the packet sniffing techniques just covered, input validation strives to ensure that no player performs an action that is invalid. This method of cheat prevention can work equally as well for both client-server games and peer-to-peer games. The implementation of input validation boils down to the simple premise that the game should never blindly execute an action from a packet sent over the network. Instead, the action should first be validated to ensure that it is valid at the point in time in question.
For example, suppose that a packet is sent over the network requesting that Player A fire their gun. The receiving machine should never assume that it is valid for Player A to fire. It should first be confirmed that Player A has a weapon, the weapon has bullets, and the weapon is not on a cool down. If any of these conditions are not met, the fire request should be rejected.
It should further be confirmed that when receiving an action for Player A, it is being sent from the client who is responsible for Player A. Recall that the code for both versions of Robo Cat in Chapter 6 performed this validation. In the case of the client-server action game, each host address was associated with a client proxy. This way, when moves are received over the network, the server only allows those moves to be applied to that host’s corresponding proxy. For the peer-to-peer RTS game, each command is issued by a specific player. When command packets are received over the network, they are associated with that specific peer. When it is time to execute the commands, the peers will reject any commands for units not owned by the peer issuing the commands.
If invalid actions are detected, it may be tempting to boot the offending player. However, you should consider the possibility that the invalid input was accidental, perhaps due to latency or packet loss. For example, suppose that players can cast spells in a particular game. In said game, let’s suppose that it is also possible for players to “silence” other players, meaning they cannot cast spells for the duration of the silence. Now suppose that Player A is silenced, which means the server will send an update packet to Player A. It is possible that in the interval prior to receiving the silence packet, Player A transmits a spell cast action. Thus Player A would be transmitting an invalid action, but not due to any nefarious reason. Because of this, it would be a mistake to boot Player A. In general, a more conservative approach of simply rejecting the invalid input will be the proper course of action.
While input validation works well for the server validating a client and a peer validating another peer, it is not particularly easy for the client to validate commands from the server. This wouldn’t be an issue for games that run on developer-hosted servers, but it could be an issue for servers that are hosted by players.
In an authoritative server model, only the server has a complete picture of the game state. So if the server tells a client that the client should take damage, the client will have a difficult time validating whether or not this damage is legitimate. This is doubly the case because in a typical configuration, the client has no way to directly communicate with the other clients. Thus, Client A has no way of verifying whether a command actually came from Client B—it has to trust that the server is sending it valid information.
The simplest and only foolproof solution to the problem of bad data from the server is to not allow players to host games. With the advent of cloud hosting, it is viable for even lower budget games to host servers in the cloud. Though there still is a cost, it is substantially less than it would be to run physical servers in a data center. Chapter 13 covers an approach to using cloud hosting for dedicated servers.
However, if your game either does not have the budget for this, or you simply want to give players the option to run their own servers, the solutions become more complex. One approach that has limited success is to maintain peer-to-peer connections between clients. This will increase the complexity of the code base and the runtime bandwidth requirements, but it would allow for some validation of the server’s information.
To see how this would work, consider a hypothetical multiplayer dodge ball game. In the standard client-server model, if Client B throws a dodge ball at Client A, this information is first sent from Client B to the server, and then from the server to Client A. To add an additional layer of validation, when Client B throws the dodge ball, it could also send a packet to all of the other clients, notifying the other clients that it is throwing a dodge ball. Then when Client A receives a packet from the server regarding the ball throw, it can validate against the packet it should have received from Client B.
Unfortunately, there is no guarantee such a peer-to-peer validation system for the server will always work. For one, just because each client is able to reach the server does not necessarily mean that each client will be able to reach each other client. This is especially the case when dealing with NAT traversals, firewalls, and so on. Second, even if all clients are reachable to each other, there is no guarantee that the peer-to-peer packets will arrive faster than the packets from the server. So if Client A has to make a decision on whether or not the server’s information is correct, it may be possible that the packet from Client B has yet to arrive. This means that either Client A has to wait for Client B’s packet, which will delay the updating of the game, or return to square one and accept the server at its word.
Software Cheat Detection
The approaches used to combat both man-in-the-middle attacks and invalid input are both relatively defensive in nature. In the case of man-in-the-middle attacks, the data is encrypted so that it cannot be read. In the case of invalid input, validation code is added to disallow bad commands. However, there is a much more aggressive approach to combatting players who attempt to cheat.
In software cheat detection, software that runs either as part of or external to the game process actively monitors the integrity of the game. Most methods of cheating involve running cheat software on the same machine as the game. Some cheats hook into the game process, other cheats overwrite memory in the game process, still other cheats are third-party applications used for automation, and some cheats even modify data files used by the game. All these different types of cheats can be detected using software cheat detection, which makes it a very powerful method to combat cheaters.
Furthermore, software cheat detection can detect cheats that would otherwise be undetectable. Take the example of a real-time strategy game that’s using lockstep peer-to-peer. Most real-time strategy games implement fog of war, which allows each player to only see areas of the map that are near that player’s units. However, recall from Chapter 6 that in the lockstep peer-to-peer model, each peer is simulating the entire game state. Thus each peer has, in memory, a complete picture of where all of the units in the game are located. This means that the fog of war is implemented entirely in the local executable, and so the fog of war can be removed by writing a cheat program. This type of cheat is commonly referred to as map hacking, and while it is popular in real-time strategy games, any game that uses fog of war can be susceptible to map hacks. What makes this difficult to detect is there likely is very little other peers can do to detect the map hack—the other peers would just see data being transmitted as normal. However, software cheat detection can successfully detect if a map hack is being used.
Another popular cheat is a bot that either plays the game in lieu of a player, or assists the player in some way. For example, bots have been used for years in MMOs by players wanting to level up or gain money even while they are sleeping or otherwise away from their computer. In FPS games, some players use aim bots in order to help give them perfect accuracy with every shot. Both of these types of bots can compromise the integrity of the game in major ways, and both can only be detected by software cheat detection.
Ultimately, any multiplayer game that wants to foster a strong community will need to consider using software cheat detection. There are several different software cheat solutions in use today. Some are proprietary and only used by specific game companies, while others are available for use either for free or with a license. The remainder of this section discusses two software cheat detection solutions: Valve Anti-Cheat and Warden. For obvious reasons, the amount of public information available for software cheat detection platforms is fairly limited, so it will be presented in broad strokes. In the event you decide to implement your own software cheat detection, be forewarned that it requires a great deal of understanding of low-level software and reverse engineering. It’s also worth noting that even the best software cheat detection platforms can be circumvented. So it is imperative to continuously update the cheat detection in order to stay ahead of those writing cheat programs.
Valve Anti-Cheat (VAC) is a software cheat detection platform that is available to games that utilize the Steamworks SDK. Chapter 12, “Gamer Services” contains an in-depth discussion of the Steamworks SDK as a whole. For now, we will focus the discussion on VAC. At a high level, Valve Anti-Cheat maintains a list of banned users for each game. When a banned user tries to connect to a server that uses VAC, the user is denied access to join the server. Some games will even ban across multiple games—for example, if a player is banned from one game using Valve’s Source engine, they are likely banned from all games using the Source engine. This provides an extra amount of deterrence to the system.
At a high level, VAC detects cheaters at runtime by scanning for known cheat programs. There are likely several methods used by VAC to detect a cheat program, but at least one of these methods is to scan the memory of the game process. If a user is detected using a cheat, they typically are not banned immediately. The reason for this is an immediate ban would make it apparent that the cheat is no longer safe to use. Instead, VAC simply creates a list of users to ban at some point in the future. This allows the system to catch as many players as possible who are using the cheat and then ban all of them at once. Players use the term ban wave for this practice of delayed bans, and it is commonly used by many software cheat detection platforms.
There is also a related functionality, called pure servers, implemented in Valve’s Source engine (and thus, can only be used in Source engine games). A pure server validates the content of users upon connection. The server has expected checksums of all of the files that should exist on the client. Upon joining the game, the client must send its file checksums to the server, and if there is a mismatch, the client is booted. This process also happens when a map transition occurs in which the level changes. To account for the fact that some games allow customization to, for example, change the looks of characters, it is also possible to whitelist some files and paths so they are not checked for consistency. Although this system is specifically in Source engine, it would be possible to implement a similar system in your own game.
Warden is the software cheat detection program created and used by Blizzard Entertainment for all of their games. The functionality of Warden is a bit less transparent than VAC. However, much like VAC, while the game is running Warden scans the computer’s memory (among other locations) for known cheat programs. If a cheat is detected, that information is sent back to the Warden server, and the user will be banned at some point in a future ban wave.
One especially powerful aspect of Warden is that updates to its functionality can occur while the game is running. This provides an important tactical advantage—typically cheat users are knowledgeable enough to not use a cheat immediately after a new game patch is released. This is both because the cheat may not even work anymore, and even if it does, it will almost certainly be detected. However, when Warden updates dynamically, it is possible to catch users that did not realize that Warden has been updated. That being said, some cheat program authors claim that their software is able to detect when Warden is updating, and in this event actually unload the cheat program before Warden finishes its update.
Securing the Server
Another important aspect of security for networked games is protecting the server against attack. This is particularly important for shared world games with central servers, but any game server can be susceptible to attack. So you should plan for certain types of attacks, and make sure you have contingencies in place in the event these attacks occur.
Distributed Denial-of-Service Attack
The goal of a distributed denial-of-service attack (DDoS) is to overwhelm the server with requests that it cannot successfully fulfill, ultimately causing the server to be unreachable or otherwise unusable for legitimate users. The reason this works is because too much incoming data will either saturate the server’s network connection, or use up so much processing power that the server cannot keep up with actual requests. Pretty much every major networked game or online gamer service has been affected by a DDoS at one time or another.
If you are using your own hardware for game servers, it can be difficult and stressful to mitigate against DDoS attacks. It involves working closely with your ISP, as well as potentially upgrading the hardware and distributing the traffic across different servers. On the other hand, if you use a cloud hosting solution for your servers, as covered in Chapter 13, some of the work to prevent the DDoS attacks is done by the cloud provider. The major cloud hosting platforms all have some level of DDoS prevention built in, and there also are specialized cloud-based DDoS mitigation services that can be purchased. That being said, you should never assume that the cloud hosting provider will completely prevent the potential for DDoS—it is prudent to still invest time in planning for and testing different mitigation strategies.
You should also consider that a malicious user may attempt to send malformed or improper packets to the server. This can be done for a number of reasons, but the simplest reason is the user is attempting to crash the server. However, a more insidious user may be trying to cause the server to execute malicious code through a packet buffer overflow or similar attack.
One of the best ways to secure your game against bad data is to utilize a type of automated testing called fuzz testing. In general, fuzz testing is used to discover errors in code that normal unit or quality assurance testing is not likely to discover. For a networked game, you would use fuzz testing to send large amounts of unstructured data to the server. The goal is to see whether or not sending this data to the server will crash it, and fix any bugs discovered by the process.
In order to find the most bugs, it’s recommended to use both fully randomized data as well as more structured data—such as packets that contain expected signatures even if the rest of the payload is random and unstructured. With many iterations of fuzz testing and fixing the bugs caught by fuzz testing, you can try to minimize the possibility of your game being vulnerable to bad data.
Any code that compares an expected byte signature or hash versus the received signature is potentially susceptible to a timing attack. In this type of attack, information can be learned about the implementation of a particular hashing algorithm or cryptography system based on the amount of time data takes invalid data to be rejected.
Suppose you are comparing two arrays of eight 32-bit integers to determine whether or not they are equal to each other. One array, a, represents the expected certificate. The other array, b, represents the user’s provided certificate. Your first thought might be to write a function as follows:
bool Compare(int a, int b)
for (int i = 0; i < 8; ++i)
if (a[i] != b[i])
The return false statement seems like an innocuous performance optimization—if a particular index is a mismatch, there’s no reason to continue to compare the remainder of the arrays. However, this code is vulnerable to a timing attack because of this early return. For incorrect values of b, the Compare function will return faster than for correct values of b. So if a user tried every possible value of b, they could actually determine which value is correct by testing which value causes Compare to take longer to return. This process could be repeated for every index, and eventually the user would be able to determine the entire certificate.
The solution to this is to rewrite Compare such that it always takes the exact same amount of time to execute, regardless of whether b or b is a mismatch. One can take advantage of the fact that a bitwise exclusive-or (XOR) yields zero if two values are equivalent. Thus, you canperform a bitwise XOR between every index of a and b, and bitwise OR those results together, as in the following rewritten Compare function:
bool Compare(int a, int b)
int retVal = 0;
for (int i = 0; i < 8; ++i)
retVal |= a[i] ^ b[i];
return retVal == 0;
One big concern for server security is a malicious user attempting to break into the server, particularly for shared world games. The goal might be to steal user data, credit card numbers, and passwords. Or even worse, the attacker might try to wipe the entire database for the game, effectively erasing the game from existence. Out of all the server security concerns, intrusions have the most possible nightmare outcomes, and should be taken very seriously.
There are several preventative measures that can be taken to limit potential for intrusion. The biggest step you can take is to make sure all of the software on your servers is kept up-to-date. This includes everything from the operating system, the databases, any software used for automation, web apps, and so on. The reason for this is that old versions may contain critical vulnerabilities that are fixed in newer versions. Staying on top of updates will help limit the options that an attacker will have to infiltrate your game’s server. Similarly, limiting the number of services the server machine will reduce the number of potential infiltration points.
The same goes for machines used by developers on your project. A common route for many intrusions is to first break into a personal machine that has access to the central server, and then use this personal machine to springboard into the server system. This is referred to as a spear phishing attack. So at a minimum, the operating systems as well as any software that accesses the Internet or network, such as web browsers, should always be updated on all of your developer’s machines. Another route to combating the springboard to the server is by greatly limiting how accessible your critical server and data machines are to personal machines. It may be worthwhile to enforce two-factor authentication on your servers, so that simply knowing someone’s password is not enough to gain access.
But despite your best efforts to prevent intrusions, you should still make the assumption that your server is vulnerable to a skilled hacker. Thus you want to ensure that any sensitive data you store on your server is as secure as possible. This way, in the event of a breach you can still limit the amount of damage done to your game and the players of your game. For example, user passwords should never be stored as plain text, because someone with access to the database would then instantly have access to all your user’s passwords, which can be particularly bad given how often users reuse passwords across several accounts. The passwords should instead be hashed using an appropriate password-hashing algorithm, such as the Blowfish-derived algorithm bcrypt. Do not use a simpler hashing algorithm such as SHA-256, MD5, or DES to secure your passwords, because these older systems can all be easily broken on modern machines. Similar to encrypting passwords, you should also ensure billing information such as credit cards is stored in a cryptographically secure manner consistent with industry best practices.
As evidenced by the widely publicized intelligence leaks in recent years, often the biggest threat to your server’s security may not be an external user. Instead, the greatest threat to your security systems might be a rogue or disgruntled employee. Such an employee may attempt to access or disseminate data that they should not. To combat this, having a comprehensive logging and auditing system is important. This can act both a deterrent, and in the event that something does happen, can provide evidence of criminal wrongdoing.
Finally, you should make certain that any important data is backed up regularly to off-site and physical backups. This way, even in the worst case where your entire database is wiped by a malicious attacker or some other calamity, you still have recourse and can restore to a recent version of the data. Having to restore from a backup is never ideal, but it is still much better than the alternative of permanently losing all of your game’s data.
Most multiplayer game engineers need to be concerned with security on some level. The first thing to consider is the security of data transmissions. Since packets can be intercepted by a man-in-the-middle attack, it is important that sensitive information such as passwords and billing information is encrypted. The recommended approach is to use some form of public key cryptography such as RSA to encrypt the data. For data only relevant to the game state, it is useful to minimize the amount of data that is sent. This is particularly helpful to reduce cheating in client-server games, because it gives clients less information to work with.
Input validation is also important to ensure that no user is performing an action when it is not allowed. Bad input may not always be tied to cheating—it is possible in a client-server game that a client simply has not received the latest updates when it sends out the command. That being said, it is important that all commands that are sent over the network are verified. This can work both for the server validating a client’s input and for a peer validating another peer’s input. For the case of validating data from the server, the foolproof choice is to disallow players from hosting their own servers.
Although it is a more aggressive approach, software cheat detection can be the best tool to eliminate cheating in a game. A typical cheat detection software will actively scan the memory of a computer running the game in order to determine if any known cheat programs are also running. If a cheat program is detected, the user in question is banned from the game, usually during a future ban wave.
Finally, it is important to protect your servers from a variety of attacks. Distributed denial-of-service attacks seek to overwhelm servers, and can be combatted in part by using cloud hosted servers. Bulletproofing your server code against bad packets can be accomplished by utilizing fuzz testing. Finally, it is important to take measures such as keeping your server software up-to-date and encrypting sensitive data stored on the server in order to mitigate the risk and damage from a server intrusion.
1. Describe two different ways a man-in-the-middle attack might be executed.
2. What is public key cryptography? How can this be useful to minimize the risk of a man-in-the-middle attack?
3. Give an example of when input validation may result in a false positive, meaning that the input validation thinks the user was trying to cheat even if they were not.
4. How might a game that allows players to host their own servers validate data sent from the server?
5. Why is map hacking in a lockstep peer-to-peer game undetectable without usage of software cheat detection?
6. Briefly describe how the Valve Anti-Cheat system works to combat players who are cheating.
7. Describe two different ways to secure a server from potential intrusions.
Brumley, David, and Dan Boneh. “Remote timing attacks are practical.” Computer Networks 48, no. 5 (2005): 701-716.
Rivest, Ronald L., Adi Shamir, and Len Adleman. “A method for obtaining digital signatures and public-key cryptosystems.” Communications of the ACM 21, no. 2 (1978): 120-126.
Valve Software. “Valve Anti-Cheat System.” Steam Support. https://support.steampowered.com/kb_article.php?ref=7849-Radz-6869. Accessed September 14, 2015.