I want to build a system where many people can play browser based simple (swf or html5) games (like snakes, car race, ludo etc). These games will be dead simple and does not require logic to be written in server.
The person who makes the highest score will win some prize.
Now the issue is securing the workflow. My approach may my incorrect, please feel free to suggest any alternative.
1. When game begins, a game id is generated.
2. When game ends, score and game id is sent back.
Problem is, Step 2 can be spoofed. Any one can send similar http request, with generated game id and any score. How do I know that score is coming from my game and its not being sent directly.
I thought of encrypting the score, but again the encryption mechanism will be there in javascript, which can easily be replicated.
Please help, thank in advance.
EDIT 1: I am not worried about sniffers, session hijacking, man in the middle attack. HTTPS will take care of all that. I am worried about user itself. He can just right click > inspect in a browser and check the request header being sent. He can easily replay same request header (just by right clicking and open in a new tab)
You can add layers of submission signing/encoding to obscure the data, and JS code obfuscation to make it harder for a user to undo that level of protection.
But ultimately you cannot solve the problem. You are placing the trust to run your code in the expected way to an untrusted client, and that naturally gives untrustable output. Spoofing the score is only one point of entry - an attacker could just as easily tamper with other parts of the client-side game logic to cheat.
Trusting the client is a perennial security problem to which there is little possible solution. For a trivial high score table that no-one cares about, you can potentially get away with a quantity of obfuscation to keep off the casual attacker, coupled with manual monitoring and pruning for obviously fraudulent submissions.
If you are considering offering actual desirable prizes, you may need to move some essential part of the game onto servers which you control. What pieces you need to protect and how is highly game-dependent and there are likely to be residual attacks that are difficult to defend against. (Consider for example the lengths that commercial multiplayer server-based games go to try to defend against client hacks like aimbots.)
I guess it depends upon the value of the data, but it sounds like the value is very low.
Pick a functionally impossible to guess ID. For example, a GUID (128 bit randomly generated value). If someone were to guess it, they get the game. But it's statistically impossible that they will ever get it right. And if you send it over HTTPS then they can't sniff it out (I'd send it over HTTPS, just because).
If you want to do better you can pick a random password to go with it, but I question if the math supports this as being necessary. It sounds like your data is crazy low value. Does it really matter?
FWIW, the bigger thing I'd be worried about is the person who decides to DoS you by asking you to store tons and tons of data for games that didn't exist...
Related
I'm developing a feature for a client in which users voluntarily take an important test online. The test is difficult and the users will be highly motivated to do well (think SATs or GRE, etc)... so there's also a high incentive to cheat. Apparently there are 3rd party services in which a human virtually monitors the test taker via a webcam, but they're really expensive and we don't quite have the budget. We still need to make it as hard as possible for a user to game the system. Some of the things we suspect they might try are:
Getting someone else to take the test for them (a pinch hitter).
Taking the test multiple times with different profiles to practice
and gain an unfair advantage.
Taking the test alongside friends or while in contact with a friends
to tell them the answers.
The question order will change, as well as the order of the answers. The test will be timed, and an "open book" format, so we're not really worried about the user looking things up online, but we can't have them sharing their screen and having others assist them. So the main concern at this point is ensuring that the user is, in fact, who they say they are (and not someone else).
Here are a few of the security measures we're considering:
Requiring the user's device to have a webcam, which we'll activate and either record/photograph the user during the test (with the user's consent of course).
Asking users to verify an arbitrary bank deposit amount (presumably via PayPal). There's nothing to stop them from opening up multiple bank accounts, but at least it's a big hassle.
Really scary terms of use that threaten legal action if the user is caught cheating.
QUESTION: Are there any other measure we can/should take to make sure our test is secure and the results are reliable?
CLARIFICATION: We realize that with enough resources and determination, any security system can eventually be beaten. The goal of this question is not to find a magically unbeatable solution, but to find ways to raise the stakes enough so that it won't be worth it for most users to cheat. In this spirit, I'd much prefer answers that focus on what can be done as opposed to what can't.
As you know there are many ways of cheating. Your goal is limit the possibility of cheating as much as possible. Cheating in online courses has been a hot topic.
A pinch hitter:
This type of attack can be conducted a number of ways. Even if you have a cam looking at the person, the video that the test taker is seeing could be mirrored on another screen. A pinch hitter could see the question and just read him the answers or otherwise feed answers the test taker in a covert channel.
Possible counters to this attack is to also enable the mic to see if they are talking to anyone. You can also record the screen while they take the test. This could prevent them from opening a chat window or viewing other unauthorized content. (Kind of like the Elance tracker)
user verification:
In order to register the person should attach a scanned copy of their photo-id. This way you are linking a photo of the person to a unique identifier, such as a drivers license number. Before the person starts taking the test, ask the user to look directly at the camera and make sure you get a good image of them that can be verified against their photo id.
A simple attack against this system is to use photoshop to modify the id. To make this attack more difficult you could verify their name against a credit/debit card transaction. The names should match on both cards.
An evercookie could be used to track machines to see if the same computer is being used. This could happen though legitimate reasons, but it could also be used to flag tests for further review. A variant on the evercookie is to drop a file with a random value or set a registry key with a random value to "mark" that machine.
As most of you know, email is very insecure. Even with a SSL-secured connection between the client and the server that sends an email, the message itself will be in plaintext while it hops around nodes across the Internet, leaving it vulnerable to eavesdropping.
Another consideration is the sender might not want the message to be readable - even by the intended recipient - after some time or after it's been read once. There are a number of reasons for this; for example, the message might contain sensitive information that can be requested through a subpoena.
A solution (the most common one, I believe) is to send the message to a trusted third party, and a link to the that message to the recipient, who then reads this message from the 3rd party. Or the sender can send an encrypted message (using symmetric encryption) to the recipient and send the key to the 3rd party.
Either way, there is a fundamental problem with this approach: if this 3rd party is compromised, all your efforts will be rendered useless. For a real example of an incident like this, refer to debacles involving Crypto AG colluding with the NSA
Another solution I've seen was Vanish, which encrypts the message, splits the key into pieces and "stores" the pieces in a DHT (namely the Vuze DHT). These values can be easily and somewhat reliably accessed by simply looking the hashes up (the hashes are sent with the message). After 8 hours, these values are lost, and even the intended recipient won't be able to read the message. With millions of nodes, there is no single point of failure. But this was also broken by mounting a Sybil attack on the DHT (refer to the Vanish webpage for more information).
So does anyone have ideas on how to accomplish this?
EDIT: I guess I didn't make myself clear. The main concern is not the recipient intentionally keeping the message (I know this one is impossible to control), but the message being available somewhere.
For example, in the Enron debacle, the courts subpoenaed them for all the email on their servers. Had the messages been encrypted and the keys lost forever, it would do them no good to have encrypted messages and no keys.
(Disclaimer: I didn't read details on Vanish or the Sybil attack, which may be similar the what comes below)
First of all: Email messages are generally quite small, esp. compared to a 50 mb youtube vid you can download 10 times a day or more. On this I base the assumption that storage and bandwidth are not a real concern here.
Encryption, in the common sense of the word, introduces parts into your system that are hard to understand, and therefore hard to verify. (think of the typical openssl magic everybody just performs, but 99% of people really understand; if some step X on a HOWTO would say "now go to site X and upload *.cer *.pem and *.csr" to verify steps 1 to X-1, I guess 1 in 10 people will just do it)
Combining the two observations, my suggestion for a safe(*) and understandable system:
Say you have a message M of 10 kb. Take N times 10 kb from /dev/(u)random, possibly from hardware based random sources, call it K(0) to K(N-1). Use a simple xor operation to calculate
K(N) = M^K(0)^K(1)^...^K(N-1)
now, by definition
M = K(0)^K(1)^...^K(N)
i.e. to understand the message you need all K's. Store the K's with N different (more or less trusted) parties, using whatever protocol you fancy, under random 256 bit names.
To send a message, send the N links to the K's.
To destroy a message, make sure at least one K is deleted.
(*) as regards to safety, the system will be as safe as the safest party hosting a K.
Don't take a fixed N, don't have a fixed number of K's on a single node per message (i.e. put 0-10 K's of one message on the same node) to make a brute force attack hard, even for those who have access to all nodes storing keys.
NB: this of course would require some additional software, as would any solution, but the complexity of the plugins/tools required is minimal.
The self-destructing part is really hard, because the user can take a screenshot and store the screenshot unencrypted on his disk, etc. So I think you have no chance to enforce that (there will always be a way, even if you link to an external page). But you can however simply ask the recipient to delete it afterwards.
The encryption is on the other hand is not a problem at all. I wouldn't rely on TLS because even when the sender and the client are using it, there might other mail relies who don't and they might store the message as plain text. So, the best way would be to simple encrypt it explicitly.
For example I am using GnuPG for (nearly) all mails I write, which is based on some asymmetric encryption methods. Here I know that only those I have given explicitly permission can read the mail, and since there are plug-ins available for nearly all popular MUAs, I'ts also quite easy for the recipient to read the mail. (So, nobody has to encrypt the mail manually and might forgot to delete the unencrypted message from the disk...). And it's also possible to revoke the keys, if someone has stolen your private key for example (which is normally encrypted anyway).
In my opinion, GnuPG (or alternatively S/MIME) should be used all the time, because that would also help to make spamming more difficult. But thats probably just one of my silly dreams ;)
There are so many different ways of going about it which all have good and bad points, you just need to choose the right one for your scenario. I think the best way of going about it is the same as your 'most common' solution. The trusted third party should really be you - you create a website of your own, with your own authentication being used. Then you don't have to give your hypothetical keys to anyone.
You could use a two way certification method by creating your own client software which can read the emails, with the user having their own certificate. Better be safe than sorry!
If the recipient knows that the message might become unreadable later and they find the message valuable their intention will be to preserve it, so they will try to subvert the protection.
Once someone has seen the message unencrypted - which means in any perceivable form - either as text or as screen image - they can store it somehow and do whatever they want. All the measures with keys and so one only make dealing with the message inconvenient, but don't prevent extracting the text.
One of the ways could be to use self-destructing hardware as in Mission Impossible - the hardware would display the message and then destroy it, but as you can see it is inconvenient as well - the recipient would need to understand the message from viewing it only once which is not always possible.
So given the fact that the recipient might be interested in subverting the protection and the protection can be subverted the whole idea will likely not work as intended but surely will make dealing with messages less convenient.
If HTML format is used, you can have the message reference assets that you can remove at a later date. If the message is open at a later date, the user should see broken links..
If your environment allows for it, you could use the trusted boot environment to ensure that a trusted boot loader has been used to boot a trusted kernel, which could verify that a trusted email client is being used to receive the email before sending it. See remote attestation.
It would be the responsibility of the email client to responsibly delete the email in a timely fashion -- perhaps relying on in-memory store only and requesting memory that cannot be swapped to disk.
Of course, bugs can happen in programs, but this mechanism could ensure there is no intentional pathway towards storing the email.
The problem, as you describe it, does sound very close to the problem addressed by Vanish, and discussed at length in their paper. As you note, their first implementation was found to have a weakness, but it appears to be an implementation weakness rather than a fundamental one, and is therefore probably fixable.
Vanish is also sufficiently well-known that it's an obvious target for attack, which means that weaknesses in it have a good chance of being found, publicised, and fixed.
Your best option, therefore, is probably to wait for Vanish version 2. With security software, rolling your own is almost never a good idea, and getting something from an established academic security group is a lot safer.
IMO, the most practical solution for the situation is using Pidgin IM client with Off-the-Record (no-logging) and pidgin-encrypt (end-to-end assymetric-encryption) together. The message will be destroyed as soon as the chat window is closed, and in emergency, you can just unplug the computer to close the chat window.
I know this is impossible, but how close can I get?
I'm creating achievements, and when a user 'gets the achievement' his browser tells him with a javascript popup, and sends a message to the server to update his profile.
I'd rather not have my users be able to just hit the webservice and get all the achievements. Signing the requests with a private key is better, but it would have to be stored in the .js file and then easily sniffed. I could obfuscate it, or do a unique one per user. And timestamp the requests.
Any better suggestions?
As the original question acknowledges, I think this is basically impossible in
situations where it's really hard to get the server to rerun what the client did.
(eg. a platform game with close timing)
Obfustication's probably your best bet. First off do a bit of crypto and include
timing information - use public/private key per user. That gets rid of the basic
traffic sniffing/replay. Obfusticate the client code too so they at least have to
put some effort into decoding it. I'd say that'd probably eliminate 99% of the
people trying to cheat. Until that last 1% writes a firefox add-on to unlock
achievements and gives it to the other 99% at least.
Beyond that, well, don't have achievements reward them with anything important.
Colin
Well the problem is, how do you determine when someone has an achievement? If it's client side, something like
quest.hasGoldenRod = true;
Then yeah, you're going to have trouble stopping them from setting that themselves.
The way to do it is to have the server mirror the actions that the client takes to ensure they actually got the item legitimately.
Then, when the client says 'I got it', the server goes 'Let me check that,' and if it can also validate that the client did indeed get it, then all is well and give them the achievement.
Signing doesn't help you. You have two approaches:
You can go for complete verification. The only way to assure this completely is to involve the server, like silky said. If the achievement is that the user got to some "area" in a game - the game sends a "Hey I got to LA!" and you go "I know you did. You've been telling me all along as you enter each new area, and I've been keeping track."
You can go for "reasonable" verification using techniques like obfuscation and timing. Have the server send a calculation function userEarnedGoldBarAcheivement down to the client that is the test function - and the function changes slightly every day (so if you send me a request with {goldBar: true, key:12345} I go "Uh, uh, that key was yesterday's!")
Suppose you are designing a PC game that keeps track of high scores. In addition to keeping local scores, a global high score server is set up that is accessed by the game over the internet. Players should be able to submit their high scores to the global high score list right after they have completed a game, or later, from their local high score list. This must be a common problem; arcade games on modern game consoles often feature a global high score list that works like this.
My question boils down to: how can you prevent someone from submitting bogus high scores? Or, stated another way, how can the global high score server be sure that a submitted score was really produced by a run through the game?
The more I thought about this, the more I think it may be an unsolvable problem.
What you'd commonly do to verify that a message originated from a certain source is have the source digitally sign the message. You could certainly do that in this case, but the real problem is that the player, by having the software, also has the software's private key. No matter how obfuscated it might be, it can be reverse engineered, or even just plucked from memory.
Another option would be to send along a replay of the player's game to the high score server, which would quickly run the replay and verify that the submitted score matches the outcome of the replay. This doesn't solve the problem, but it certainly makes it more difficult to forge a bogus high score if you also have to produce a very complex replay that "proves" it.
Is this a problem that has a solution, or is it really unsolvable? Are there techniques used by the home game console developers to prevent this sort of exploit, or do they simply rely on the console preventing unauthorized code from running?
For a PC game where the score is generated by the client, this is not a solvable problem since the client is inherently untrustworthy.
The only thing you can try to do is make it harder for someone to submit a fake score.
Some thoughts:
Protect the in-memory score.
You can use API's like CryptProtectMemory to hide the score in memory - a simple memory write will not work. However, with an attached debugger or via injecting code into your process, they could still modify the score. You can look into various schemes for trying to defeat debuggers.
Protect the score en-route to the server.
You can encrypt the data being sent to the service, as you suggest, but since the untrusted party has control over the key, this is merely obfuscation and offers no solid protection.
Validate the score at the service.
I'd be loathe to do this, beyond very simple checks. A bug here will result in you rejecting valid scores. It'll be impossible to distinguish between cheaters and strong players.
At this point, you really have to ask your self if the engineering effort is really worth it. What if someone posts an invalid score? What do you actually lose? I would do the bare minimum to protect against a kid with a simple script. I.e., don't have your score submission be just:
http://myservice.com/submitscore.aspx?PlayerName=Michael&Score=999999999
I would just use simple protection in memory against casual snoops, some simple obfuscation on the wire (hash the score with a server cookie) and be done.
To my knowledge, this is unsolvable.
I have seen many people try to obfuscate the encryption key. I have seen a few people include other sanity checks like time elapsed, or enemies remaining. I have never seen one that sends a replay, though of course it is possible.
In a website that will remain unamed, they setup a fake send high score routine that is easily found. If a perpetrator uses it, their IP address will be automatically banned from future updates.
"Another option would be to send along a replay of the player's game ... This doesn't solve the problem, "
Really? Why not?
"you also have to produce a very complex replay that "proves" [the score]."
Are you suggesting someone could fake the replay? Reason out a super-high-score solution without actually playing the game? Fake the timestamps and everything? Pull a Donald Crowhurst?
Why not just play the game rather than attempt to fake a log of playing the game?
Or... if it's that easy to fake a history of game play that leads to a super high score, perhaps the game is misdesigned. If the game is "hard", the person must make all the right choices. If the game is easy, then the score doesn't reflect the player's choices and is fakable.
Think of it this way. Pick any game or sport. Someone says that -- say -- Switzerland beat New Zealand in a yacht race. You would challenge them by seeking substantiating details on the venue, the boats, the teams and the individual races to convince yourself it was true. Certainly, they could fake it, but if they've got a rich set of details covering the race, then... how's that not "proof"?
Forget the cryptogaphic issue; if your code can be hacked on the local machine, how do you keep someone from setting a crazy high score artificially and then transmitting it using the existing trusted mechanism?
Until you can establish trust in the code itself, a crypto mechanism for the communications isn't going to be the real problem.
Send the hash of the (software + a random salt) along with the score. Check this hash with the server. If it matches (meaning that the software is unaltered) accept it. Otherwise, the score comes from a "modded" version of the game. Reject it. The random salt should change every time the hash is generated (current sys time or something like that)
Check Quake III Arena source code. Their version was quite fool proof. Unfortunately, I don't remember the link now.
My boss is against requiring our users to have secure passwords, even going so far to request they be setup by default to have passwords the same as their username. What should I do in this situation? What would you do?
Update - Some users have brought up the question of whether the application needs high security. This isn't credit card information for example but does include sensitive information and a mailing list management and sending functionality.
Make the best case you can for strong passwords and then, unfortunately, if they do not see your point of view either do what they asked or find a better job.
What you're told.
...
Then respecfully let the superior know in writing what problems that will cause.
Do not CC anyone. This is my opinion, of course. If you CC it will look obvious. You really just want security but you have to cover yourself. You don't have to be a horse's behind about it though.
Keep it in your sent box, print it, whatever, if you are truly concerned.
edit - You do what you're told unless it is some sort of question of moral turpitude. Then you simply document what you did and why you did it. Just remember that if you do not document it - it did not happen. Documenting is something you should always be doing.
As a compromise there are way better defaults, like using the user's serial number, year of birth, initials, some combination, depending what you have on hand. Not the most secure but not the least either.
Does your application require high security? If the data controlled by your software is not sensitive and the risk to the user is low, perhaps you really don't need strong passwords.
If your app does pose a significant risk to the user if passwords are allowed to be weak, you should make that case as best you can, in writing. If you can quantify risk and liability, do so, but ultimately you will have to leave the decision up to your superiors.
There's nothing wrong with a default password the same as the username provided that the system requests that the user creates a new password the first time the user logs in. You then allow anything as a password if there is low security requirement. If you're handling sensitive data then password strength needs to be of an appropriate level. You haven't said what data you're hiding. There's no point in having super strong passwords (12 chars, lower case, upper case, digit and symbol and no words from dictionary) if it's an intranet based time tracking system. If you're accessing something like a tax record database then you'd need at least two level authentication - string password and one time key generation.
You should hit him hard. Explain him/her what sort of bad publicity might happen because of this, also depends on the data, data protection act and similar stuff can actually cause serious liability. Basically doing it such can be considered as a software defect therefore company can be responsible for the results.
Basically you need to give him a reason which will bite him, scare him. That's how you sell security and insurance :)
If you boss can't figure out such a simple thing and can't trust guys like you at the end, maybe you should start looking for a new place which you can actually use your own potential instead of dealing with these sort of issues.
This is poor security.
If it can result in, for example, identify theft for your users, then you have a very serious social responsibility to improve the security. You are essentially dealing with people's lives. Go to your boss, go to his or her boss. Print out these comments and bring them along. Go to your legal department and tell them how much exposure this causes. If your company was dumping toxic waste whistle blower laws would apply. Personal information and identify theft is no less serious. Do everything in writing to cover yourself and to provide a paper trail of evidence for the lawsuits that will surely follow. Don't allow your company to deny any knowledge of the risk after the fact. Companies that knowingly implement horrible security that results in identify theft should fail in the market place and deserve nothing but shame, ridicule and failure.
If on the other hand this poor security can result in comparatively minor things then your your effort to improve the security can also be scaled back from what I describe above.
Email him your concern (in a non-aggressive way). Give the logical attack vector, reveal what will be exposed. Close by asking for his confirmation taht this is his instruction. Then send to him (only him, as previously suggested)
Email archive both your original email and his confirmation. This will cover you if something happens.
Argue the case for having stronger passwords but also make a compromise. Have the passwords as defaulting to the username with certain letters replaced with numbers perhaps? This all depends on the system as well. If this is an internal system, it could be quite hard for somebody to gain access to the system & do any harm.
Do what your boss says, but make the passwords expire within a relatively short time period.
I would put together a summary document on password policies, benefits of strong passwords, etc and submit it to him for review and try and make it part of company policy. If they still don't like it then do what they ask, as they are the end client and you have done your part to educate them of the pitfalls.
why using user/pasword in the first?
to log user activity?
the operating system asks for it?
if you want to connect an action (whatever) with an user, I as an user would require that my password be safe!
if your boss is afraid, that he may loose "knowledge", if a user is away, and he needs to get access to that uesers data, require everyone to write down his password in a sealed envelope.
if your boss does not trust you, kündige!
Peter
I would consider what is behind the request to have it that way first.
Is it really an active user with username+password what should be being set up in the first place? i.e. perhaps the user should be receiving an email with a link to activate :)
When does the sensitive information comes into the system? Assuming it is input by the user, just have an activation step where the user changes the password (or is the first time (s)he has a password for that matter).
Notice that if you are working with sensitive information, it is likely there is a law relating to it. I would also look into that, if it is illegal it makes for a strong case, and in that case you should Really consider saying plain no (explaining the reason first of course).
Did he say they had to be all lowercase...
Did he explicitly say they had to not include numbers...
You should hack into his account. Then he will know why username=password dont work.
I've run into this before, where they didn't want to use a secure password &/or lock down their computers.
Then it happened our website had been hacked into (not b/c of a password breach, but b/c of flawed component/module for the CMS that we used - but that's a different story) and in a few different occasions, people have logged into the exec's computer to view a few inappropriate things.
The reason for this explanation is to say that it wasn't until this and a few other case studies that I brought to their attention that they understood just how important it is for secure passwords.
As a solution, you may try to do some research on case studies where a breach has occurred on systems or sites where the information stored or protected wasn't terribly important, but the damaged cause and money it took to recover was substantial - such as someone setting up a phishing scam on your site, the holding hostage a server or site & having to wipe clean the whole box to start over, or some other type of breach.
Anyways, take it for what it's worth.
A few things come to mind that you might want to share with your boss -
The biggest security threat isn't outsiders, it's the folks you work with. If there has been someone fired with cause since you've been there, bring that up with your boss - "What if XXXX had access to other people's accounts?" That person many not steal data, but they may try to vandalize the system or mess with data out of spite. Or could they even share that data with a competitor?
Propose a somewhat stronger default as a compromise - username and 4 digits of home phone number. It's not much stronger but it does make guessing a little harder.
People can make fairly secure passwords by using mnemonics. However, you need to train people in how to do that. Offer to hold a session with your users on how to create secure passwords. Honestly, it's not just good for where they work but for anyone who shops or banks online. Something that's easy for IT people who have to juggle multiple passwords may be harder for others.
BTW, I found a nice javascript generator of mnemonic passwords.
http://digitarald.de/playground/mnemonic-password-generator/
I've found situations where a password is shared by several people, because sometimes security is less important than other stuff. Specially in intranets.
A solution can be to store the IP address of each user. It's a security measure closer to security cameras than to locks, but it might be enough for what your boss has in mind.
Slough may be onto something - but it might be too harsh.
Maybe take a combination approach.
Do what`s asked - but when presenting it, make sure it breaks, or you have some mechanism that will show how or why it is not a secure approach. (This will go through a review process before being implemented right?)
Also find any documentation that describes "best coding practices" from respected industry peers either in books or online or even office colleagues that may be able to back up your point of view. Present your sources, and if their ignored, you've done your duty and due diligence, and the final outcome will rest on the superiors shoulders.