My PhoneGap android app recuires a user login and it needs to show the user certain information after it has logged in. (App retreives XML from the PHP server, by using AJAX)
I've searched on many blogs/forums and many stackoverflow posts, trying to come up with the best security options/features.
I want to implement the following security options.
Secure traffic by using HTTPS (http +ssl)
[server side] User agent checks.
Do CRC checks on the phonegap JS file and send the result along with the information request. Then make the server compare the CRC result with the result it should be. (So if someone decompiled the App, changed code, and compiled it again... we would know)
The app can only REQUEST data from the server. And not delete/update any data.
Obfuscate/encrypt the javascript files... just to make it a bit harder to de
And if the following is possible with Phonegap
Add the android UID/Device ID to my database. So only whitelisted device can get access.
Should I use more security features?
HTTPS must be used for the life of the session. OWASP A9
The user-agent is an attacker controlled variable. There is no
point in checking this variable becuase it is trivial to spoof.
CRC is not a secure hash funciton. It is triival to bypass this
check my making a modification and then adding padding to create an
identical CRC. If a user modifes your app, then can remove your
bullshit CRC check.
The server MUST enforce access control, assume an attacker can
send you any request.
Do not rely upon (in)security though obscurity.
A user can send any request they would like, so they can spoof this
identifier.
An attacker does not have to modify your JavaScript in order to modify HTTP requests. An attacker can use a BURP proxy or similar tool to intercept and modify requests before they reach your server. Read the OWASP top 10, make sure your backend API is free from common defects.
Related
On my current website i use Jquery and POST requests between different PHP files to get and update information. Currently om not using either SSL or home grown encryption to hide the plain-text in the headers, that will come later.
I'm wondering how to prevent client side POST modification besides sanitizing and validating the inputs before using them. Some of the information passed between the PHP documents are hard to predict, therefore hard to validate.
Got any tricks up your sleeves?
I was thinking i could use session stored data in PHP to validate that it was the actual server that sent the request. But i guess that session data can be "tapped" in many ways?
Choose one:
You can store data in session between requests (more server memory)
You can sign the data sent to the client using an HMAC (more server cpu), then check it on the next request on the server
There's no excuse not to use HTTPS these days. 3 free vendors now.
Two important things about HTTP - It is, by nature, stateless, therefore every request is independent of any previous requests and secondly and more importantly - it is based on trust. Once data hits the server (specifically the php script), it is impossible to know where that request originated and if the data can be trusted. This means the only way to ensure data is clean and secure is if it is sanitized and validated.
Because of the inherent trust with HTTP, any client can forge a request with malicious intent. There are ways to make this harder, and depending on what you are trying to protect you can spend more time and resources to do so. These steps are different depending on what you are trying to accomplish. Are you trying to stop a malicious user from stealing others users information? Are you trying to stop them from accessing data on your server that they should not (sql injection, directory traversal)? Are you trying to prevent the user from impersonating another user (session hijacking)? Are you trying to prevent the user from injecting malicious javascript (xss)? Depending on your goal and your risk, you would invest time and energy to try and prevent one or all of these things.
Lastly, HTTPS only mitigates a man in the middle attack (maybe session hijacking) and not any of the above mentioned scenarios, so you still need to clean and scrub all data that your php receives.
I am trying some stuff out with phonegap and I had a question concerning the security that I cant figure out.
So lets say I want to add something in a db. I let phonegap do an ajax post to a php file on a server with the vars and this php file will insert it in the db.
But anyone who would know where this php file is located and knows the data it wants can do an ajax post and insert data right?
I was reading about giving the php api a token. But I also was reading it is very easy to decompile a phonegap apk so it wouldnt be hard to get this token right?
So how can I make sure the php file on the server only accepts posts made from my phonegap app?
You can't. There is no way to guarantee they only come from your application. You can however ensure any calls come from a specific known user of your application.
You have an untrusted client with which it is impossible to embed a secret within without compromising the secret. You can make it harder, such as encrypting your JS and packaging it encrypted, then relying on Apple's DRM to secure your key, but for someone vaguely determined that will not stop them. Your AJAX end point exists and as the insecure client needs to communicate with it somehow there will always be a way to discover the client's secret.
However, typically this isn't an issue. What you can do, is exchange a secret with the client that is tied to a single user so that any calls to your API are on behalf of that user, and that user only (presuming that secret is kept secure - they don't lose their device etc). You can then use this secret to either encrypt or sign your outgoing AJAX call. This ensures someone can only affect their own account (e.g. only update their own account, only upload content tied to their account etc), and can't make arbitrary calls on behalf of other users.
This is enough for many types of application - though you haven't provided any detail about what your AJAX call does. No one is going to deliberately leak their own "personal" secret (though if theft is a concern, or you have higher security requirements then you could implement 2FA or more).
Personally, if this was anything non trivial, I wouldn't advise rolling your own system anyway. Security is difficult to get right, and there are many existing authentication systems out there (e.g. OAuth2) which have been tried and robustly tested in the wild.
Say I have a PHP application and want the users data to be encrypted before it it gets to the server (to prove to users that their data will not be data mined or resold for advertising).
Similar question was asked here ( Secure Javascript encryption library? ) and implies that this is not going to work, but with the increase in privacy interest amonsgt users this requirement is only going to get greater over time.
Example, using the Stanford library (http://crypto.stanford.edu/sjcl/) a web form has an additional ‘long’ password field which the user pastes in (probably from email for example)
sjcl.encrypt(txtPassword, txtFormFieldToBeEncrypted)
The encrypted data is sent to the PHP page, and the process is reversed when the page is loaded.
Would this work if the users used Chrome or another browser that remembers form values - obviously this is not a secure result, but would this be effective enough to keep the users information private from the host server?
EDIT: Just to be clear, I am only interested in making the information invisible to the host server, and understand that this solution wont protect from 3rd party attacks
Protection on the page is useless, for the simple fact that the encryption key / mechanism will also be in the scope of the page and can thus be tampered with by a malicious party (or by the user itself when inspecting the page).
To avoid data going over the line unencrypted there is also no reason to "roll your own"(tm), because for that there is SSL.
If you want to make sure that the data that you receive on the server was actually originating from a page that you control, you can rely on CSRF protection.
First of all use SSL it is for an only way for secure communication. If you make encryption in JavaScript it is trivial to decrypt your message (because all your code with keys is public).
If you worry about CFRS attack use anti-forgery token (more here: http://bkcore.com/blog/code/nocsrf-php-class.html)
It's perfectly possible to do this, Lastpass for instance built their business model on it. All their server does is store an encrypted blob which they cannot do anything with, all encryption and decryption happens on the client; including a Javascript implementation in the browser. The entire blob of encrypted data is downloaded into the client, where the user's password decrypts it; and in reverse on the way back up to the server.
So if your question is whether it's possible: absolutely. It's also a lot of work, since you will need to be providing the same en-/decryption code for as many platforms as you want to support. You'll also need to secure every context where that code will run, to prevent third parties from injecting code which would allow them to access the client side decrypted data. So, everything needs to go over SSL with no 3rd party content being allowed to be injected.
Here are a bunch of reasons why javascript encryption in the browser is almost always a bad idea.
You need to think deeply about your trust model. Do the users trust the server? If not, there is no hope for trustworthy javascript crypto since the crypto software itself comes from the server. If the users do trust the server, why does the data need to be encrypted client-side? Just use SSL to secure the connection, then have the server encrypt the data before storing it.
When I developed Wave Framework, I put a lot of attention on the security model for API requests. I had to make sure that the API requests can be made over HTTP from where-ever possible while at the same time secure against potential middle-man attacks, data tampering and more.
I ended up essentially building a GET string from the input data and generating a SHA-1 hash from it while salting it with API profile secret key. This works really well and protects the API as much as I need.
But my API also allows for things such as file uploads over HTTP. At the moment I am ignoring file upload related data entirely (I use it for cache signature but not for data validation). This means that a malicious middle man could technically change file contents as it is being transferred.
Are there any alternatives? Sure I could implement this when files are sent server side (such as calculate file contents as part of the validation hash), but that is not an option if the upload is through web browser and initiated through JavaScript?
How have other frameworks handled this? I've tried to search but could not find enough information. Thanks!
If I understand you right, your framework creates a web page where users may upload files. The only way to protect against man-in-the-middle in this scenario would be to use ssl.
Remember that a man-in-the-middle in this case also would be able to change the web page the user is interacting with when he uploads the data. Say that you created a javascript that in some way encrypted the document using a password that the user typed in. The man-in-the-middle could easily change the javascript to encrypt his fake document and throw away the real document.
If security is an issue on web and you need to protect against man-in-the-middle, then SSL is a requirement. There is no way around it.
I have an Android application from which I want to upload some data to a database on my web server. As the MySql java library has a size of about 5 mb, I don't want to include it with the application.
So I'll make a HTTP request for a php script and send the data with the URL as parameters. How do I make sure that only I can call this? I don't want people to sniff up the URL and call it outside my application.
Thanks
Use a simple static token to identify the client is yourself or in an advance way, first authenticate with a username/password, generate a token and use this token for further transactions .This token can expire after some time.
option1: http://[your request url]&key=xyz
where xyz is known only to you
option 2: first ping server with username password and upon successful validation get a dynamic token [dKey], store it locally.
then for further requests.
http://[your request url]&key=dKey.
option 2 is the one normally being followed.
The short answer: you cannot prevent sniffing.
But you can make sniffer's life harder by implement a some sort of internal authentication, GET/POST predefined parameters (or dynamic, but calculated by algorithm you only know how) exchange, hidden header fields, etc.
But all this could also be sniffed/reverse engineered.
A possible Overkill Way would be using some sort of asymmetric private/public key encryption/signature. Such as RSA. Your app will only include public key, and sign the request data with it. And your server-side will have a secret private key, it will use it to check validity of client requests.
I know very little about android - but it's not really relevant to the question.
If you want to prevent someone from sniffing the URL (and authentication details?) then the only option is to use SSL. On the other hand if you merely want to prevent other people from accessing the URL, its simply a question of authentication. If you're not using SSL, then that means you need to use sessions and a challenge-based authentication to avoid people sniffing the traffic. You could do this via digest authentication or roll your own code.
C.