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.
Related
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.
For my school, we have to do these "Advisory Lessons" that tell you about College, etc. After completing the lesson, I am wondering if I would be able to replicate the same process using a set of requests from a PHP script with cURL.
I went through the lesson again, this time with Firebug on and an HTTP Analyzer.
Much to my surprise, the only GET requests were sent out during the entire lesson.
In case your curious, here is what the "Lesson" window looks like. It's sort of powerpoint-type thing where you read the slide and then some slides have questions on them. At the end, there is a quiz and if you don't pass it, the lesson doesn't count.
My question is this: If I were to setup a PHP/cURL script that logged into my account, and then made every single one of those requests, would the lesson be counted as complete?
Now obviously it's impossible for you guys to know how their server works and such...
I guess what I am saying is, is there any hidden content or fields that you can pass through a GET request? It just doesn't seem like the lesson window is passing enough info to the server for it to know if the lesson was complete or not.
Thanks so much for any advice and tips on my project!
EDIT: Here is my official test run (please don't do it too many times):
As many of you hinted, it did not work....but I am still not completely sure why.
Like you say, we can't speak to the details of their server, but it is possible to do these kinds of things with GET requests only because servers can use cookies and store state (associated with these cookies) on the server.
This gives the appearance, probably, of passing extra hidden information to the server.
You can research cookies, and even that jsessionid thing that is appearing in their URLs. That BTW tips you off that they are using at least some Java. :)
The lesson application may very well be storing data in a session or some other persistant data store server-side and using a token from your browser (usually a cookie or a GET parameter) to look up that data when needed.
Its a kinda complicated task. With only cURL you can't emulate execution of javascript code, AJAX requests etc
I am not sure what you are trying to do. For one HTTP is stateless protocol meaning the server gets request and gives a response to that particular request (that might be GET, POST or whatever and might have some request parameters). Statefullness in system usage is usually achieved by server creating a session and setting up a cookie on client side to pass session id in later requests. Session id is used to recognize the client and track his session. Everything you send during request is plain text. What response you get most likely will depend on session state and will also be a plain text. There is nothing hidden on a client side about client side. You just don't get to know what information server keeps in session and how requests are processed based on that and information you give during requests.
[I hope that this question is not too broad, I think that the subject is very interesting but I incourage you to tell me if it's off-policy.]
My scenario is this:
I have a LAMP website who stores also sensitive data and documents
Only registered users are allowed to operate on the site, and only on certain data and documents. Users are stored in $_SESSION variables
Most of the pages implement a sort of rudimental permission control, but some important DB operations are called via AJAX
AJAX security is implemented very poorly, as anyone that is that smart can tamper with the request sending whatever id they like and delete records with brutal simplicity
Asking for a complete book on security is obviously a bit too much (and I'm already reading and trying a lot on the subject), let's say that my main concern is if AJAX pages should be treated with special regards, as I need to secure the whole software to prevent hacks and other problems.
let's say that my main concern is if AJAX pages should be treated with special regards
Not really. They should be treated almost exactly the same as any other request. All HTTP requests come from outside your system and are under the control of the client (so can consist of, more or less, anything the user can imagine).
You might be returning JSON, you might be returning a complete HTML document, you might be returning XML — but the format doesn't matter, the data does.
If the request is for sensitive data, then you need (on the server) to authenticate the user and then make sure they are authorised to view / edit that data.
The only difference is how you present a "You are not authorised" message. You can't simply return an HTML document with a login form when you expect the browser to load data into XHR. The response needs to be appropriately formatted and the JavaScript needs to be able to handle it.
I have a LAMP website who stores also sensitive data and documents
You should store as little sensitive data as possible. Especially when you are not sure how to keep this information secure/private. Use OpenID or something for your authentication for example. I really like LightOpenID for it's simplicity. I created a little example project/library to see lightopenId in use. It simplifies using OpenID by using openID-selector. When you use OpenID you also use secure OpenID providers the passwords are also not transmitted over the wire in plain-text but protected by https/SSL.
Only registered users are allowed to operate on the site, and only on
certain data and documents. Users are stored in $_SESSION variables
Yup that's what sessions are for.
Most of the pages implement a sort of rudimental permission control,
but some important DB operations are called via AJAX
You should read up on OWASP top 10. at least. (Don’t stop at 10.)
AJAX security is implemented very poorly, as anyone that is that smart
can tamper with the request sending whatever id they like and delete
records with brutal simplicity
See previous section. Read up on OWASP top 10 section at least. Somethings which a lot of people overlook for example are CSRF for example.
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?"