How to secure a REST API for mobile applications? - android

I am trying to add a REST interface to Django for a mobile client. The mobile client will use JSON over HTTPS. I have not been able to find the "best" way to accomplish this for mobile devices. From searching around, it seems that #2 is more favorable to #1:
Use HTTP authentication and establish a cookie based session. All transactions will occur over HTTP and JSON messages will only contain commands or data.
Pass the username and password (encrypted) within each JSON msg for all transactions and do not rely on cookie-based sessions.

I would recommend sending the username / password first with a login call. The JSON will pass back an authToken or accessToken which the mobile device will send back for all subsequent calls. You will then check to make sure the authToken is valid. This is the approach many API's take. In their database they will bind the API key to the users account that they logged in with.

OAuth is overkill unless you want to make these services available to other developers (which they would access on behalf of your end users). Better to go with option 2, but I would recommend using Digest Authentication as opposed to Password Authentication. Combine that with SSL and you are definitely good to go.

Number 2 is preferable, and rather than roll your own, I would recommend using OAuth authentication if possible. Both client and server libraries are readily available for use on most platforms now. Check http://oauth.net for details.

So long as you're using actual encryption and not base64 or some homegrown obfuscation algorithm, #2 is fine and dandy. You might also want to consider the route many companies take, which is binding an API key to a username.

Related

Should I encrypt a user's password before sending it to the server?

I want to authenticate a user by allowing him to create a username and password. Since I only find old posts about it, I'm creating this one.
Should I encrypt the password before sending to the server? If so, how should I do it? If not, should I use some specific configuration in my POST request to the server?
Is there any reliable third party api that I should use?
I know that Google has an androidx API for this things, but it's still in alpha.
If you use HTTPS protocol to comunicate with the server the data are already encrypted before beeing sent, anyway I suggest you to execute an additional encryption using Cipher.
PS see this question for more How to encrypt String in Java
You may make a basic obfuscation like Base64 or something like that, as Marco mentioned, HTTPS already secures the channel and information wouldn't be seen by a man in the middle.
Instead of encryption you may add a security validation that the HTTPS certificate is trusted, so that using Proxies such as Charles Proxy is also forbidden.
Encryption assumes an encryption key which needs to be securely distributed. Since the password (or a derivate of it) needs to be stored server side for subsequent authentication I would recommend to send the password in clear text at least when registering the username / password. Of course assuming that HTTPS, enforcing a secure protocol and hostname verification, is used. The benefit is that you don't add an implicit dependency to a specific algorithm to the server API. Instead the server application can hide this as an internal detail when storing the password (or a derivate) in the database. This makes API evolution less painful.
It is often recommended to use certificate pinning (i.e. "hard-coding" a server certificate client side) but this may be overengineering depending on your use case as it will require certificate lifecycle management.
All this said. You probably would benefit from using a third party service (e.g. AWS cognito) for authentication, at least in the short term. This way you can more easily implement 2-factor authentication when creating the account, login abuse prevention, password recovery, etc

User authentication methods for REST api project

My web server has a REST API. I need to add user authentication to my app, and my thought process behind it is this:
Get the user's username and password from the app form
Encrypt the password and Base64 encode both the username and password
Send the data to the REST API over HTTPS
Web server verifies credentials, returns errors or success
Is this secure? I see a lot of mentions of OAuth2. What is it? What does it do better than my process?
The fact that you used the word "encrypt" for the users password instead of "hash" demonstrates you have fairly limited knowledge about this. This will almost certainly result in you messing up your authentication procedures somewhere along the line and put your users private information at risk.
A really important point about OAuth2 is that it can be used with many existing third party providers (Google, Facebook, Twitter, etc) with minimal effort from you.
You don't need to do anything to store credentials or even authenticate users. The third party takes cares of all of this and simply provides the client with a token (long random string) which is then passed to your server. Your server then talks to the third-party server to make sure the token is valid (and gain any info you need, like the users' name, email address or other information).
You really should consider using it if you can. The big companies put a lot of effort into securing their authentication methods and you gain all of that by making use of it.
A final nice point is that users don't need to create and remember credentials for (yet) another account.
Google has some docs to get you started and includes an OAuth playground to test how it works in practise.
A very basic explanation of OAuth2 is that the user will log into your system, with it encrypting both username and password before sending it, then if it gets authenticated, it will send back a token to the user.
Thereafter, whenever the user tries to contact the web server, it will send this token along with each API call. This is how it makes sure that non-authenticated people can't access your web server.
So basically your current method includes parts of the OAuth2 standard, but not the most important part (The token).
In your situation, how would you stop non-authenticated people from accessing your web server? If the project is small, then the risk of this is not that large.. But for larger companies, this is a real threat that needs to be dealt with.
You should really try to understand the difference between encryption and hashing before providing an authentication portal for your users. There are many different hashing algorithms you can use. I've personally used BCrypt in the past and I have a related SO Question about it as well. You can find implementations of pretty much all the popular algorithms in pretty much all the major high level languages these days.
Obviously if you don't want to do all that you can use an OAuth provider, who will take care of all the hard bits like storing the passwords securely, protecting the database and all the other security aspects for you. There are many reliable OAuth providers, Google, Facebook, Yahoo, etc. etc.
One thing to bear in mind would be the environment in which your app is hosted. OAuth does depend on having a connection available to the OAuth provider's servers every time a user wants to access your app. So, if you are behind a corporate firewall or similar which may block access to websites like Facebook, this might be a big problem.
I personally prefer token based authentication for my API projects. If you're not familiar with token based authentication you can read this SO Question and this link.
The general concept behind a
token-based authentication system is
simple. Allow users to enter their
username and password in order to
obtain a token which allows them to
fetch a specific resource - without
using their username and password.
Once their token has been obtained,
the user can offer the token - which
offers access to a specific resource
for a time period - to the remote
site.

secure a REST API for use by Android clients

We're developing a JSON REST API in Rails to be consumed by an Android application, which we are also developing. Is there any way to secure the API such that it can only be used by our specific Android application?
The API is read-only, and does not involve any kind of user-related or otherwise sensitive information. But to the extent that is reasonable we'd like to prevent abuse and restrict its use to only our app.
I could easily add an authentication token to the API and distribute it with the app, but:
We'd probably have to move the API over to SSL, if we use BASIC auth.
It's probably trivial for a determined person to open up the Android APK binary and uncover the auth token anyway.
The situation seems analogous to a café posting their WiFi password on the shop counter- you have to give the secret out to everyone who wants to use your service, so it almost seems pointless to have it in the first place.
What's the most reasonable approach to take?
Wanting to secure a probably public undocumented API so it can only be accessed by one application, means you want to stop people from using your API who are determinate of using your API.
Meaning people who would try everything possible to use your API.
If this is not the case adding a Auth token won't be trivial but at least a big stepping stone for people who stumble upon your API. And not a very bad idea to implement this.
Because this authentication isn't user based but application based and you don't want authentication to rely on user input. The request must be purely done so by the application.
Meaning you will have to do so anyway(adding hardcoded token). Only you make it very very difficult for a determined person to uncover the access and request tokens and the methods.
It depends on the situation, but I would go for the SSL and hardcoded token.
Some extra security:
Release an access token to the application which only need to send a
request token periodically. Meaning less chance people intercept the
hardcoded request token, but a session based access token which
expires. Maybe just do this once for every application install.
Encode this request token before sending it through the air. Meaning
people have to decompile your app.
Obfuscate code (make it more difficult to decompile).

How to make a Android client request secure?

I have a android application which sends updates about the purchases for the server. What I do now is, I encrypt the purchases and some other shared details into MD5, using the same key generator in server side and Android Client side. But if some one decode the APK file that person can easily make the calls by generating keys. What is the best way to prevent these kinds of attacks?
Use HTTPS to communicate with you server in order to protect data in transit. Do not try to invent a secure protocol. If you want to restrict access to server API's use some form of authentication: username and password (over HTTPS) or better yet some sort of authentication token (OAuth, etc.). If you store keys and/or passwords inside the APK, anyone can extract them by decompiling the APK. If you want to protect against this, you need to use token authentication where tokens expire and can be invalidated if compromised.
Best Solution is that you implement some web service which will return you a access key(will change every time you want to get access key) which you will use every time to communicate with your server in POST method. This is most secure method and being used by every good sites like Facebook, Twitter etc.
Sine my problem was basically about updating the server with in-app purchases, I ended up doing Public/Private key authentication at the server end. Android suggest to verify receipts on client, but we just forward the receipts to server and did validation there using the public key.

Protecting my REST requests in Android?

I have a server side script which gets some data that my application uses. Naturally, I don't want anyone else access the data aside from my app. I've heard it's possible to see which url's the device connects when using a certain software. How can I prevent these programs seeing the url's I'm calling to? Or is there a better way of securing the requests?
Only thing I can think of is using a password key in the url (and check if it matches on the server side):
http://example.com/getdata?key=897ihrduiuyqewudiew&get=something
but that probably isn't enough for a secure authentication. And the sniffer programs could still get that url. Any simple way of doing this more securely?
The easiest way is to use HTTPS. This way, only the server to which you connect to can be known by the sniffer.
There are other methods that use complex challenging to have a unique key only valid for a short period of time / a single request, like WSSE (see this article http://www.xml.com/pub/a/2003/12/17/dive.html )
There is very little you can do in order to protect the server requests. Someone will always be able to see the URLs your application hits and using a password in the query string won't help. In order to secure your application you need to use HTTPS and some form of authentication. The user will need to provide a username and password in order to connect.
If I understand you correctly, you should implement mutual authentication. Basically, you have certificates on both your client and server. When a request is made to the server, the server verifies that request is signed by a known client.
So, even if a sniffer knows the url and attempts to issue the same request to the server, it would be rejected since it is not signed by a known client. I am quite new to this as well, but that is the general concept. This blog has the basic steps.
http://blog.callistaenterprise.se/2011/11/24/creating-self-signed-certificates-for-use-on-android/
http://blog.callistaenterprise.se/2011/11/24/android-tlsssl-mutual-authentication/

Categories

Resources