I have created an iPhone application which fetches data held on a server in an XML file. How do I check that the request for the data is coming from my app and not from some other source such as another iPhone app or a desktop browser since currently you could just trace the iPhone request on your LAN with Wireshark and then use the captured URL to load the data in a desktop browser. I'm thinking I'm going to need to serve the file via PHP or something and use some sort of User Agent validation or a challenge-response sequence. If someone could provide a code sample I'd appreciate it.
Short answer: You can't. But you can indeed make it harder.
Whatever you do, it will be possible to circumvent it - user agent validation is extremely easy to circumvent; challenge-response will require disassembling of your app, but it's still possible.
However, all your nice protections won't help against network sniffing. Unless you also encrypt the transfer someone can simply sniff the plaintext data instead of breaking your "protection".
IMO the main question shouldn't be "How do I protect it" but rather "Why would somebody want to get the raw data? Why shouldn't he get it?"
Related
I am new to the world of programming and I have learnt enough about basic CRUD-type web applications using HTML-AJAX-PHP-MySQL. I have been learning to code as a hobby and as a result have only been using a WAMP/XAMP setup (localhost). I now want to venture into using a VPS and learning to set it up and eventually open up a new project for public use.
I notice that whenever I send form data to my PHP file using AJAX or even a regular POST, if I open the Chrome debugger, and go to "Network", I can see the data being sent, and also to which backend PHP file it is sending the data to.
If a user can see this, can they intercept this data, modify it, and send it to the same backend PHP file? If they create their own simple HTML page and send the POST data to my PHP backend file, will it work?
If so, how can I avoid this? I have been reading up on using HTTPS but I am still confused. Would using HTTPS mean I would have to alter my code in any way?
The browser is obviously going to know what data it is sending, and it is going to show it in the debugger. HTTPS encrypts that data in transit and the remote server will decrypt it upon receipt; i.e. it protects against any 3rd parties in the middle being able to read or manipulate the data.
This may come as a shock to you (or perhaps not), but communication with your server happens exclusively over HTTP(S). That is a simple text protocol. Anyone can send arbitrary HTTP requests to your server at any time from anywhere. HTTPS encrypted or not. If you're concerned about somebody manipulating the data being sent through the browsers debugger tools… your concerns are entirely misdirected. There are many simpler ways to send any arbitrary crafted HTTP request to your server without even going to your site.
Your server can only rely on the data it receives and must strictly validate the given data on its own merits. Trying to lock down the client side in any way is futile.
This is even simpler than that.
Whether you are using GET or POST to transmit parameters, the HTTP request is sent to your server by the user's client, whether it's a web browser, telnet or anything else. The user can know what these POST parameters are simply because it's the user who sends them - regardless of the user's personal involvement in the process.
You are taking the problem from the wrong end.
One of the most important rules of programming is :
Never trust user entries is a basic rule of programming ! Users can and will make mistakes, and some of them will try to damage you or steal from you.
Welcome into the club.
Therefore, you must not allow your code to perform any operation that could damage you in any way if the POST or GET parameters you receive aren't what you expect, be it by mistake or from malicious intents. If your code, by the way it's designed, renders you vulnerable to harm simply by sending specific POST values to one of your pages, then your design is at fault and you should redo it taking that problematic into account.
That problematic being a major issue while designing programs, you will find plenty of documentation, tutorials and tips regarding how to prevent your code to turn against you.
Don't worry, that's not that hard to handle, and the fact that you came up with that concern by yourself show how good you are at figuring things out and how commited you are to produce good code, there is no reason why you should fail.
Feel free to post another question if you are stuck regarding a particular matter while taking on your security update.
HTTPS encrypts in-transit, so won't address this issue.
You cannot trust anything client-side. Any data sent via a webform can be set to whatever the client wants. They don't even have to intercept it. They can just modify the HTML on the page.
There is no way around this. You can, and should, do client side validation. But, since this is typically just JavaScript, it can be modified/disabled.
Therefore, you must validate all data server side when it is received. Digits should be digits, strip any backslashes or invalid special characters, etc.
Everyone can send whatever they want to your application. HTTPS just means that they can't see and manipulate what others send to your application. But you always have to work under the assumption that what is sent to your application as POST, GET, COOKIE or whatever is evil.
In HTTPS, the TLS channel is established before and HTTP data is transfered so, from that point of view, there is no difference between GET and POST requests.
It is encrypted but that is only supposed to protects against mitm attacks.
your php backend has no idea where the data it receives comes from which is why you have to assume any data it receives comes straight from a hacker.
Since you can't protect against unsavoury data being sent you have to ensure that you handle all data received safely. Some steps to take involve ensuring that any files uploaded can't be executed (i.e. if someone uploads a php file instead of an image), ensuring that data received never directly interacts with the database (i.e. https://xkcd.com/327/), & ensuring you don't trust someone just because they say they are logged in as a user.
To protect further do some research into whatever you are doing with the received post data and look up the best practices for whatever it is.
I'm writing a mobile game where the user sends his highscore to a PHP server.
I want to verify in the server that the HTTP request comes only from the mobile devices. I want to refuse calls that a malicious user may send via curl or other HTTP clients with a fake score.
What is the standard, usual way of doing this?
I thought that I could encript the HTTP message in the mobile client, but then I would need to release the binary with the encription key, which could be retrieved if decompiled.
Thank you.
Take a look at this:
https://github.com/serbanghita/Mobile-Detect
It is pretty accurate, however it won't stop clients who are faking their User-Agent.
Generally the best way however is not to let the client make any decisions.
Take a game like Eve Online for example. Every action you make is sent as a user action to the server, the server then validates the action and makes the appropriate decision.
If the server relied on the client to decide how much damage a ship is doing, the game would be subject to no end of trainer hacks.
You can use JavaScript to fetch information about the user's client, such as Browser CodeName, Browser Name, Browser Version, Platform, User-agent header, User-agent language, and so on.
There are probably viable libraries out there (maybe something like Flosculu's mentioned) that can aid you with mobile specifically detection, but you must understand that all of those information can be manipulated anyway, it mainly depends on HOW you transfer the data, so maybe you shouldn't be over-thinking this but instead focus on safe data transfer methods.
A quick search pointed to this mobile detection scripts though.
But again.. you can't rely on anything like this but if it's not too much time-consuming, then by all means add another validation to the script if it makes you feel better :)
I'm currently writing an Android app at the moment, that accesses a PHP file on my server and displays JSON data provided by my MYSQL database.
Everything works great and I love the simplicity of it, but I'm not too comfortable with the fact that someone could just type in the URL of this PHP file and be presented with a page full of potentially sensitive data.
What advice would you give me to prevent access to this PHP file from anyone except those using my android app?
Thanks very much for any information.
The keyword is authentication. HTTP-Authentication is designed just for that purpose!
There are 2 forms of HTTP-auth:
Basic: easy to setup, less secure
Digest: harder to setup, more
secure
Here is the php manual.
And this is what you can do in your android app.
There isn't really a fool-proof way to do this. However you can require the user agent to match that of your application. You can also hide a private key in your application that is passed as POST data to your PHP file. Now, neither of these will stop someone who is determined to get at the raw output, but it will slow down the people who are just screwing around killing a little time seeing what they can accomplish.
Why not only enable a valid response if the request is sent with the following header:
Content-Type=application/json
If the request doesn't pass it as the Content-Type, then you just terminate the script (as regular browsers usually want to get text/html or similar things). It's not really worth locking everything tight shut, as if your app can get the data from your server, any user would have the opportunity too.
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 have a web application that pulls data from my newly created JSON API.
My static HTML pages dynamically calls the JSON API via JavaScript from the static HTML page.
How do I restrict access to my JSON API so that only I (my website) can call from it?
In case it helps, my API is something like: http://example.com/json/?var1=x&var2=y&var3=z... which generates the appropriate JSON based on the query.
I'm using PHP to generate my JSON results ... can restricting access to the JSON API be as simple as checking the $_SERVER['HTTP_REFERER'] to ensure that the API is only being called from my domain and not a remote user?
I think you might be misunderstanding the part where the JSON request is initiated from the user's browser rather than from your own server. The static HTML page is delivered to the user's browser, then it turns around and executes the Javascript code on the page. This code opens a new connection back to your server to obtain the JSON data. From your PHP script's point of view, the JSON request comes from somewhere in the outside world.
Given the above mechanism, there isn't much you can do to prevent anybody from calling the JSON API outside the context of your HTML page.
The usual method for restricting access to your domain is prepend the content with something that runs infinitely.
For example:
while(1);{"json": "here"} // google uses this method
for (;;);{"json": "here"} // facebook uses this method
So when you fetch this via XMLHttpRequest or any other method that is restricted solely to your domain, you know that you need to parse out the infinite loop. But if it is fetched via script node:
<script src="http://some.server/secret_api?..."></script>
It will fail because the script will never get beyond the first statement.
In my opinion, you can't restrict the access, only make it harder. It's a bit like access-restriction by obscurity. Referrers can be easily forged, and even with the short-lived key a script can get the responses by constantly refreshing the key.
So, what can we do?
Identify the weakness here:
http://www.example.com/json/getUserInfo.php?id=443
The attacker now can easily request all user info from 1 to 1.000.000 in a loop. The weak point of auto_increment IDs is their linearity and that they're easy to guess.
Solution: use non-numeric unique identifiers for your data.
http://www.example.com/json/getUserInfo.php?userid=XijjP4ow
You can't loop over those. True, you can still parse the HTML pages for keys for all kinds of keys, but this type of attack is different (and more easily avoidable) problem.
Downside: of course you can't use this method to restrict queries that aren't key-dependent, e.g. search.
Any solution here is going to be imperfect if your static pages that use the API need to be on the public Internet. Since you need to be able to have the client's browser send the request and have it be honored, it's possibly for just about anyone to see exactly how you are forming that URL.
You can have the app behind your API check the http referrer, but that is easy to fake if somebody wants to.
If it's not a requirement for the pages to be static, you could try something where you have a short-lived "key" generated by the API and included in the HTML response of the first page which gets passed along as a parameter back to the API. This would add overhead to your API though as you would have to have the server on that end maintain a list of "keys" that are valid, how long they are valid for, etc.
So, you can take some steps which won't cost a lot but aren't hard to get around if someone really wants to, or you can spend more time to make it a tiny bit harder, but there is no perfect way to do this if your API has to be publically-accessible.
The short answer is: anyone who can access the pages of your website will also be able to access your API.
You can attempt to make using your API more difficult by encrypting it in various ways, but since you'll have to include JavaScript code for decrypting the output of your API, you're just going to be setting yourself up for an arms race with anyone who decides they want to use your API through other means. Even if you use short-lived keys, a determined "attacker" could always just scrape your HTML (along with the current key) just before using the API.
If all you want to do is prevent other websites from using your API on their web pages then you could use Referrer headers but keep in mind that not all browsers send Referrers (and some proxies strip them too!). This means you'd want to allow all requests missing a referrer, and this would only give you partial protection. Also, Referrers can be easily forged, so if some other website really wants to use your API they can always just spoof a browser and access your API from their servers.
Are you, or can you use a cookie based authentication? My experience is based on ASP.NET forms authentication, but the same approach should be viable with PHP with a little code.
The basic idea is, when the user authenticates through the web app, a cookie that has an encrypted value is returned to the client browser. The json api would then use that cookie to validate the identity of the caller.
This approach obviously requires the use of cookies, so that may or may not be a problem for you.
Sorry, maybe I'm wrong but... can it be made using HTTPS?
You can (?) have your API accessible via https://example.com/json/?var1=x&var2=y, thus only authenticated consumer can get your data...
Sorry, there's no DRM on the web :-)
You can not treat HTML as a trusted client. It's a plain text script interpreted on other people's computers as they see fit. Whatever you allow your "own" JavaScript code do you allow anyone. You can't even define how long it's "yours" with Greasemonkey and Firebug in the wild.
You must duplicate all access control and business logic restrictions in the server as if none of it were present in your JavaScript client.
Include the service in your SSO, restrict the URLs each user has access to, design the service keeping wget as the client in mind, not your well behaved JavaScript code.