I am planning on making a game with actionscript 3.0 (flash). However, I am having some security issues on saving user points.
To be more specific, read below and you'll understand what's the exact problem.
You are starting my flash application. PHP creates a session for your username. Playing for few minutes and reaching 750 points.
You click on "Save my points" button.
It connects "game.php?points=[]" with your point amount, hence, game.php?points=750.
PHP connects to MySQL and does an update/insert query with the username you entered when opening application, and gets the points with $_GET['points'] as you can see on 3.
The issue is,
Anyone who could directly browse "game.php?points=999999999999" would have his points saved in the database.
I thought about encrypting the points, however, Flash is a client-side application and anyone could change the "points" value with an application like "Cheat Engine". Once they change the points, encrypted points will automatically be generated by Flash.
I also thought about creating a private key for each player on their signup and encrypt accordingly, but it also won't work because once an user change his points with Cheat Engine, flash will automatically encrypt the points with given private key, hence, another useless theory...
Some people suggested me to use SSL, just because popular companies like Zynga uses it, but I am looking for other theories here.
Any ideas on this case, except using SSL?
Ps. The game will be a MMO, so securing data transaction is an essential.
For a real secure approach you need to move your game's logic to the server as much as possible and ideally make the flash movie just an interface to show the game's current state to the user.
Check out Yeldarb's post in this thread for a good explanation.
First of all SSL doesn't help you at all. It sounds like you have never heard of Tamperdata.
This is a classic CWE-602 violation. Cryptography does not address these problems because the attacker has more control over the application than you do. There is no place to hide a secret.
Related
I have a dynamic page where it should take data from a db. So the approach I thought of was to create the dynamic page with this php code at the top
<?php $pid = $_GET["pid"]; ?>
Then later in the file it connects to the database and shows the correct content according to the page ID ($pid). So on the home page, I want to add the links to display the correct pages. For example, the data for the "Advertise" page is saved in the database in the row where the pid is 100. So I added the link to the "Advertise" page on the homepage like this:
Advertise</li>
So my question is, anyone can see the value that's send on the link and play around by changing the pid. Is there an easy way to mask this value, or a safer method to send the value to the page.php?
The general concept you're looking for is Access Control. You have a resource (in this case, a page and its content), and you want to control who can access it (users, groups, etc), and probably how they can access it as well (for example, read-only, read-and-write, write-but-only-on-the-first-Monday-of-the-month, etc).
Defining the problem
The first thing you need to decide is which resources you need access control for, and which you don't. It sounds to me like some of these pages are supposed to be "public access" (thus they are listed on some kind of index page), while others are supposed to be restricted in some way.
Secondly, you need to come up with an access policy - this can be informally described for a small project, but larger projects usually have some structured system for defining this policy. For each resource, your policy should answer questions like:
Do you have some kind of user account system, and you only want account holders (or certain types of account holders) to access it? Or, are you going to send links to email addresses, and want to limit access to just those people who have the link?
What kind of access should each user have? Read-only? Should they be able to change the content as well (if your system supports that)?
Are there any other types of restrictions on a users' access? Group membership? Do they need to pay before they get access? Are they only allowed access at specific times?
Implementing your policy
Once you've answered these questions, you can start to think about implementation. As it stands, I think you are mixing up access control with identification. Your pid identifies a page (page 100, for example), but it doesn't do anything to limit access. If your pages are identified with a predictable numbering scheme, anyone can easily modify the number in the request (this is true for both GET requests, such as when you type a URL into an address bar, and POST requests, such as when you submit a form).
To securely control access there needs to be a key, usually a string that is very difficult to guess, which is required before access is granted. In very simple systems, it is perfectly fine for this key to be directly inserted in the URL, provided you can still keep the key secret from unauthorized users. This is exactly how Google Drive's "get a link to share" feature works. More complex systems will use either a server-side session or an API key to control access - but in the end, it's still a secret, difficult-to-guess string that the client (user or user's browser) sends to the server along with their request for the resource.
You can think of identification like your street address, which uniquely identifies your house but is not, and is not meant to be, secret. Access control is the key to your house. Only you and the people you've given a key to can actually get inside your house. If your lock is high quality, it will be difficult to pick the lock.
Bringing it together
Writing code is easy, designing software is hard. Before you can determine the solution best for you, you need to think ahead about the ramifications of what you decide. For example, do you anticipate needing to "change the keys" to these pages in the future? If so, you'll have to give your authorized users (the ones that are still supposed to have access) the new key when that happens. A user-account system decouples page access control from page identification, so you can remove one user's access without affecting everyone else.
On the other hand, you also need to think about the nature of your audience. Maybe your users don't want to have to make accounts? This is something that is going to be very specific to your audience.
I get the sense that you're still fairly new to web development, and that you're learning on your own. The hardest part of learning on one's own is "learning what to learn" - Stack Overflow is too specific, and textbooks are too general. So, I'm going to leave you with a short glossary of concepts that seem most relevant to your current problem:
Access control. This is the name of the general problem that you're trying to solve with this question.
Secrecy vs obscurity. When it comes to security, secrecy == good, obscurity == bad.
Web content management system. You've probably heard of Wordpress, but there are tons of others. I'm not sure what your system is supposed to do, but a content management system might solve these problems for you.
Reinventing the wheel. Good in the classroom, bad in the real world.
How does HTTP work. Short but to the point. A lot of questions I see on SO stem from a fundamental misunderstanding of how websites actually work. A website isn't so much a single piece of software, as a conversation between two players - the client (e.g. the user and their browser), and the server. The client can only say something to the server via a request, and the server can only say something to the client via a response. Usually, this conversation consists of the client asking for some resource (an HTML web page, a Javascript file, etc), to which the server responds. The server can either say "here you go, I got it for you", or respond with some kind of error ("I can't find it", "you're not allowed to see that", "I'm too busy right now", "I'm not working properly right now", etc).
PHP The Right Way. Something I wish I had found when I first started learning web development and PHP, not seven years later ;-)
It is always safer to $_POST when you can, but if you have to use something in the query string, it is safer to use a hash or GUID rather than something that is so obviously an auto-incremental value. It makes it harder to guess what the IDs would be. There are other ways values can be past between pages ($_SESSIONs, cookies etc), but it is really about what you want to achieve.
Sending it to php is not an issue, should be fine.
What php does with it afterwards... that's how you secure.
First thing I'd do is make sure it's an integer.
$pid=(is_int($_GET['pid']))? $_GET['pid'] : 1; //1 is the default pid, change this to whatever you want.
Now that you know you're dealing with an integer, use $pid after that and you should be good to go.
I am an iOS developer & developed a web services app which has been live on App Store for a year. Now I decided to make this app available cross-platform - beginning with Android, for which I hired an Android Developer.
Until this hire, all the web related code & data (PHP / MySQL / XML) was managed & fetched by me alone - so I did not worry much about the security. But now, with addition of another developer I have following concern:
The app sends POST request which includes how many rows to fetch - then a PHP script gets that many rows from MySQL & returns them in a well formatted XML. My concern is that now the employee will also know about the whole process & although he will not have direct access to PHP scripts OR MySQL database, he can still misuse it in a number of ways. For example, he can create a URL on web browser with a POST request for 100000 rows even - which will let him have all the data in an XML.
What measures should be taken to counter this? (Yes, I can force a hard limit of 40 in above particular case, but it is not an ideal or generalized solution.)
BTW, I did an extensive google research on this topic & to my understanding, the above problem is known as "Semantic URL attack". But I was not able to figure out the right solution for it. Using "Sessions" is suggested, but according to my understanding "Sessions" is only helpful if we have password based user authentication - which is not the feature of my app.
Any help would be highly appreciated.
First you must be aware that if you have no protection and allow just anything, people will be able to do anything, as simple as that. So as I understand, you don't want to use the standard protections: i.e. users having login credentials, and using per-case defensive programming.
Okay, then one partial solution would be to compute a hash:
you want to query the server with the parameters P
you compute H=hash(P)
you send ?p=P&h=H to the server
your server receives ?p=P&h=H and computes H'=hash(P)
if H' != H, then the server denies an answer
You would have to compute the same deterministic hash function in php and in your mobile app, preferably a very complex one, mixing your own dark encrypting algorithms with md5, sha1, synchronized threads, etc.
If you worry about the attacker to repeat an old query with the right hash, you can make a more complex handshake: first send to the client a random number, which will be a part of the hash to compute. Or something based on the datetime, the ip, or whatever.
Of course if the attacker reverse engineers your code, he can find out the hash function, but it would take him some work at least. You can obfuscate your client's code if you want to make his job harder.
As a testimony, I have used this sort of technique against lame attackers on services which didn't require a registration. Unless the attacker is a pro and badly wants your private data, it works.
I have an PHP Application. If I have logged in that application I am trying to pass the parameter as querystring through an iframe to the asp.net page.
Is there any other way to implement other than using an iframe?
Instead of having the PHP application submit data to your ASP application, it would be better if they could natively and securely share some of the data.
How?
Well, your goal is having one script tell the other that the user has been logged in, right? In PHP, this is usually done by putting something in the $_SESSION. Your ASP application can't read $_SESSION, though. You'll need to use something else.
When the user logs in, create a unique value. Maybe the result of hash_hmac over some interesting data? Whatever it is, it should be unique every time it's created and unguessable. Don't throw in things like the user's IP address or the current time.
Save the unique value to a database table that both applications can read. Also store other information that will help identify the user, such as her identifier (user_id or whatever you have on hand).
So, the PHP code that logs the user in has created this unique value and stuck it in a shared database table. Now, the PHP application should forward the user to your ASP application. Include the unique value in the request.
When the ASP application receives the request, it will look for the unique value. If it's found, it can look in the shared table. If the value is found in the table, it can then take whatever measures it needs to in order to mark the user as logged in.
Once the ASP application has logged the user in, then it should delete the unique value from the shared table. The user can be forwarded to wherever she was going in the first place.
By making the key usable only one time, and only after a successful login in the PHP application, you'll reduce the possibilities of abuse by malicious or curious users. All of the important information will be hidden in the shared database table.
Be warned that this is an overly simplistic implementation of "single sign on" and is full of caveats and edge cases. While it might work for you, it might not be the best solution. Given your question history, it looks like you've been struggling with similar issues for quite some time. You might want to give some thought into using a slightly more "industry standard" SSO mechanism. SAML is the 800 pound gorilla of SSO standards. I normally wouldn't wish it on my worst enemy, but maybe it's the thing you're really looking for here.
Also, don't use iframes, they're cookie eating disasters in some browsers.
I'm making a simple game with Java / .net as client and using php webserver.
Now when someone finishes the level, quit or starts a new game the client sends information on a php Page that stores them in a mysql database.
Now i wouldnt that the users cheat.
To use the game client you need a username and password.
The client sends the number of times that they played the game, which player has defeated, how much points earned. So if i send clear information someone with a sniffer could see which php page I call and copy the information a send to the webserver.
So what's the best security/check system in this case?
I was thinking about use any crypt system that i usable in java vb.net c# and php (like des , md5) but I would like to know if this is the better solution or not.
Update The clients dont use The Web Browser to comunicate with the WebServer. It's WinForm application for example that call php pages to get information and to update data on Mysql DB
Thanks a lot
Some things you should know before continuing:
Everything that is on the client browser can be inspected. This includes all calls you make back to your database server. Encryption doesn't matter for this because, obviously, your javascript code will be the part encrypting/decrypting the data. Javascript can easily be looked at to get the keys.
Even Flash etc can be decompiled by those willing to spend the few minutes working it out.
Don't wait until they have completed all of their games to send info to your database. Do so as the actions occur.
You can only make it a little hard, not impossible, to cheat when using javascript as the game engine in your browser. By "a little hard" I mean it might take an hour for someone with even halfway decent programming skills to defeat... most likely much less.
Regarding sniffers. It doesn't matter if your site is SSL enabled or not. This only protects the information once it leaves the computer. It is not going to do anything about a sniffer located on the client machine.
To sum up: your only real defense here is to make cheating something that is not worth anyone's time to do.
The best option would be to have the application use a webservice and the Client application encrypts the message before sending, but unless you put in some aditional salted data (such as a timestamp to try and mitigate any replay attacks) then you'll still be open to people being able to 'easily' cheat.
.Net has some good WCF service options, and although I've never used WCF with a php endpoint the idea of WCF is to allow cross technology communication, the best bet would be to do some research into that field.
Also to note, MD5 is not an encryption method, it's a Hashing algorithm, meaning that once the data is hashed it can't be recovered.
I wrote a game in c++ using SDL. The game currently updates a highscore to my game site by making a post with curl if the user has logged in. The problem that I am having is that the post provides the url to the php file that receives the post on my server, and the variables that the post uses. Last night someone from china figured this out and created 5 accounts and then posted ridiculously high highscores to those users. Is there any way I can make this more secure?
Would ssl work? I've been reading about ssl all morning, and I got curl to verify that ssl is installed, but I honestly dont even know where to start with getting my php verification page communicating with my game using ssl. I'd really hate to take the whole hiscore feature down because I've already invested so much time into all of this.
At this point I am looking for the simplest solution to prevent someone from making a form and posting new hiscores to the php page.
Any help would be greatly appreciated.
You could add a small layer of security by passing not only the high score, but a hashed version that is validated on the PHP side.
e.g.
{hs:"2000";hash:'843ed7842a6bd864162022e48b84a668'}
Posted to your PHP script, that then checks,
if($hash==md5('secret'.$hs)){
//UPDATE HighScore
}else{
//Discard, flag spammer
}
The quickest solution would be to keep an eye on the high score list, delete impossible-looking scores, and blacklist known cheaters.
However, for a longer-term solution, could you possibly send a list of the players' timestamped "physical input" (mouse clicks, key presses, etc.) along with the high score?
The server could then perform some logic using the input (perhaps even running that input through a game client running on the server) to determine whether the high score is valid.
If your game uses random numbers, you'd have to send the initial random seed as well.
Once you manage to implement this, you could fairly easily create a replay system, too, which would allow players to share replays of their games with each other.
You can add salt to data, and only app on c++ knows it, and server
Or you can`t?
SSL itself won't be enough to stop people from posting high scores. There are a couple approaches I can think of to begin with:
Ship your code with a secret key that is used to encrypt the high score before sending it to the server. This has the downside that someone could reverse engineer your game to get the key. This is probably okay though, if you don't think someone would go through the trouble. Crypto++ is a C++ encryption library that you could use for this. You probably want to use symmetric-key encryption.
What I think some other games do is to use some aspect of the game along with just the raw high score value to make a submitted score invalid if it didn't contain the game state.