I am developing an Ionic App which consumes data from a Laravel 5 RESTful API. All the connections are protected (GET, POST, etc.) by username/pass and user roles, except the user creation.
My first doubt about security is to disallow connections from outside the App, avoiding thousand of user creations, overloading our server resources.
My idea is, when an user installs the app and opens it for the first time, to create a secret token which will be sent in every connection. Then check the device UUID and the secret token to ensure this is an authorized app.
What do you think of securing the connections this way? There is a better idea?
You need to look a JWT (Jot) JSON web tokens, they will solve the security issue. This can contain user id and other data like access level. Not things like security information or card information.
When a user authenticates Laravel sends them back a JWT which you store in local or session storage this replaces backend sessions.
It is generated by the backend using the parts that can be decrypted by the frontend and using a secret key to encryt the signature, if any of it is tampered with it will fail and deny access.
Every request angular will append the token to the header using a request interceptor and Laravel middleware will decrypt it and allow access to the route they need or return a error code '404' maybe.
If after install this authentication layer you can limit usage at user level on the backend.
But this should sort most of your issues, it a bit of a change in thinking but it does work and it solves a lot of sessions issues you get with ajax calls and it make load balancing easier because all server are looking for a token it can manage.
I was also encountering the same problems. But after search in google for a while I came to the conclusion that you can put up several walls against hacker, but for someone who is hell bend on hacking your app(ninja hacker) will find ways to use your app in malicious ways.
I also came across various ways you can protect your backend server(after google). These step generally make it difficult to use your app maliciously.
You can encrypt strings url using some algorithm and use encrypted string in program ie. https:\google.com\ is encrypted into something like \h09ae\hff00\hebab\h.... then in program String url ="\h09ae\hff00\hebab\h.." This way someone decompiling the app can't find your server backend url. In this case you need to decrypt the string url before you can use it.
Send sensitive data using HTTPS and inside the body of the request
You can verify if request is coming from the device by using google token. For this you will have to use Google API Console. Refer this link for proper android tutorial on this topic.
Lastly, sign key used when you create your apk is unique and ensure that your apk is not tampered with. So generate hash key of your sign key before it is upload to google play and save it in your server and programmatically get hash value of sign key and send it with very request to your backend.
Hope is helps you..
Related
I have a stateful php web application made in Symfony that uses cookies to keep alive the session of the logged user in the application(I have worked always like that, I'm really new in REST services).
I'm making a REST API using the business logic of this web application, so I can use it in different environments (Android at the moment).
In order to keep private the API, I follow the symfony cookbook(http://symfony.com/doc/current/cookbook/security/api_key_authentication.html), so the requests are served through a 'apikey' sent in header of every request.
At the moment, this 'apikey' is a dummy string hardcoded in my android code.
What I first thought to do with this 'apikey' is a login screen in Android that send to the API an user and password, those credential will be checked on the server side and if they are correct, send to the client a 'apikey'(based on those credentials) and then, somehow, store it in the client and then send it in header of every request of the API.
I'm misunderstanding something with this 'apikey' method? (probably yes, while I'm writting this it seems to me that this apikey is a more 'static' concept).
Isn't this idea a kind of 'stateful' that is against REST pattern? I mean, I keep stored something that is checked on every request.
What I want to achieve is to have a login in Android, check credentials in server side and then(if this check is ok) let the android app make calls to the API in a secure way...
How I should proceed then?
Thank you for your time!
I'm also learning such things with Android and Symfony. What i've come to understand is your API Key should be unique to every user, meaning that every user should have, as subscribed to your website, an API Key, which represents them. It will work like a unique login, except that using REST, you only need the API Key to be authentificated, instead of a login and a password.
In this case, your API Key should be hard to find. I guess you should use the user's ID and login, since they have to be both unique identifier, and make something out of it, like encrypting.
If you've learn more since, it'd be a pleasure to hear from you experience.
I've implemented the ApiKey "mode" in my Symfony web app.
From my perspective, after correct user connection (using login and password), you can generate a key resulting in the sha1 encryption of the concatation of any unique user info with the result of uniqid.
I'm currently building a web application which is an AngularJS frontend that communicates with a RESTful API built using Laravel. I'm making good progress, but finding it hard to get my head around how to handle user authentication.
I've been advised that I should be using OAuth for authentication, and I've decided to use it seen as it could be a learning experience for me as well. The package I'm using to handle this is oauth2-server-laravel.
The basic user story is that users can register their username/password combination for the application, and they then log into the application with that same username and password. They're only authenticated by their username and password, and not by any client secret. After login, they should be given an access token which will be send along with every future request to authenticate them on different API endpoints.
The OAuth2 library has a "password flow" grant type which seems to be what I need, however it also takes client_id and client_secret parameters, which I don't want. The request URI is something like this:
POST https://www.example.com/oauth/access_token?
grant_type=password&
client_id=the_client_id&
client_secret=the_client_secret&
username=the_username&
password=the_password&
scope=scope1,scope2&
state=123456789
But what I want is just:
POST https://www.example.com/oauth/access_token?
grant_type=password&
username=the_username&
password=the_password
How am I meant to provide a client ID and secret of a user that has yet to authenticate?
Is there a different grant I can be using, or is what I want to achieve just not suited for OAuth at all?
Take into account, that client id and client secret aren't parameters that you have to force your end-user to pass. They are static and defined in/for your client app (angular app in this case).
All you need to do is to create a record for your main app in oauth_clients table, and create a scope with full access in oauth_scopes table, and send this values when requesting token.
And that's all in fact.
Also, you may want to consider using implicit grant flow in case of building js-only application, because storing client secret and refresh token in a js app is insecure. Using implicit grant in a final product may look like login window on soundcloud and is more secure as the token is obtained server-side without exposing client secret.
Another way to go, if you still want to use password flow is creating a proxy for refreshing tokens. Proxy can hide your refresh token in encrypted http-only cookie, and your js-app don't ask your api for new token, but the proxy instead. Proxy reads refresh token from encrypted cookie, asks the api for new token and returns it. So the refresh token is never exposed. If you set token ttl for an hour let's say, then stealing a token would be quite "pointless*" in case of a normal application, and stealing refresh token would be "impossible*".
*Of course if someone really want he probably could hack it any way.
And yeah, i know this all looks a bit hacky - modal windows for logging in, proxy etc. But also searching on this topic i couldn't find any better and more elegant way of doing it. I think that's still a lack that all js-apps have to deal with if you want a token based authentication.
You are missing something with the OAuth specification. The client_id and client_secret are really important when asking for an access token when using the password method of OAuth v2. In fact, they are important for every method that gives you an access token. They identify the application or the server that has perform the request.
For example, let's say you have your API, 2 mobile applications and another server that do some tasks with your API. You will create 3 clients with their own client_id and client_secret. If your application has various access levels (they are called scopes in OAuth v2), the client_id corresponding to the other server will be able to call functions of your API that require the scope admin whereas your mobile application will only be able to call functions of your API that require the basic scope if you have defined scopes like this.
If your API grows up in the future, this is really essential. Another example, let's imagine you have given an API key (a pair client_id and client_secret) to one of your friend and he has build a nice mobile app with your API. If one day he starts doing naughty things with your API, you can't stop him very easily. Whereas you could have just removed his key pair if you had followed OAuth v2 principles.
OAuth v2 is not an easy thing to understand, take the time to read specifications and good tutorials before developing your API.
Some useful links :
The official RFC : https://www.rfc-editor.org/rfc/rfc6749
A tutorial on Tutsplus : http://code.tutsplus.com/articles/oauth-20-the-good-the-bad-the-ugly--net-33216
Just to add a bit to plunntic's excellent answer: remember "client" is not related to "user", so when I use a password flow I just define the client_id and client_secret as constants on the AngularJS app to tell the api backend: hey, this is the browser app that is being used to request a token.
This is more of a procedure question question than a code fault one so please be kind if I have posted in the wrong place.
I have successfully authenticated a gplus user client-side so the browser is holding the google id ready for me to use. I now want to post some data to my website with that id as the user id but i want to protect it meaning I don't want just anyone with someone else's gplus id to be able to post to my web app (it has to be the authenticated user at that time).
Should I install the php serverside sdk and use that? If so how do i merge the client-side data with that?
Thanks
You're absolutely right about wanting to get the ID in a secure manner to make it hard to impersonate. There are two main options, both properties of the authResult object that comes back to the sign in callback:
Send the 'code' to the server. This is part of the OAuth 2.0 flow, and can be exchanged on the server side for an access token. From that you can make API calls as the user, and retrieve the user ID and other details. You can be confident who the user is, as only Google could have generated that code. This would involve using one of the client libraries to handle the token exchange.
Use the id_token. This is a base64 encoded blob of JSON which includes the user ID (and email address if you requested the 'email' scope). What makes it secure is that it includes a cryptographic signature, which the server can verify, so it cannot be created by someone other than Google. The id token can be used to get the user ID, and so can be used for looking up the user on the server, but doesn't give access to make API calls. The benefit is that it only requires up to date certificates for verification which don't change that often, so most calls require no further network traffic from the server to verify the user.
Which you use is up to you, but both will require some code on the server. In general, if you don't need to call any Google APIs from the server, or are concerned about maximum login performance then use the id_token. There's a bit more about that sort of architecture here: http://www.riskcompletefailure.com/2013/11/client-server-authentication-with-id.html
You can even combine the two. The first time a user signs in (when they see the consent screen) the code exchange will return not just an access token (for making calls), but also a long-lived refresh token, which you can store securely in a database. If you store that, you can use the id_token to look up the user quickly, but still use the refresh token to help with API access.
i have two questions...both of them are about security issues on android app..
From my app are photos sent to my ftp server,so i need to have stored ftp,user and pass..what is the best way to to that? I am affraid that these values can be easily read from code by reverse engineering..i was thinking about shared preferences but i think it is not enouhg...or to send request to my server which returns pass to ftp server (this is part of second question:)
In app a communicate with php server (create order then in app biling and finally confirmation that order was already paid...i have to write secure communication between android and php..(now android send json data by post method to php server..so if somebody cinds out url and json format of data..he is could create ordef and confirm it)..in app is no login or registration process..i was thinking abou asymetric cryptography with public key on android and private key on server..or maybe SSL is a solution..i am very confused so any advices are welcome..
I dont know how to secure app whne reverse engineering of apk is possible..
Instead of using FTP create simple API for your application which allows to post an image. That would be better and more secure solution. Android has few built-in methods for HTTP POST requests.
SSL secures just communication between. Most of commonly known applications doesnt store password in files, just use API request to validate credentials and obtain token which will be used in future requests. You can set timeout for this token and create one token per device. This is much safier, because its easier to cancel token than to inform the user that the password was leaked :)
Use well-known solutions as mentioned public-private key with autentification tokens (token generated with private key + device specified data such as DeviceID etc). Do not store passwords, even encrypted ones.
I'm writing a RESTful Webservice with the Slim Microframework and use GET for reading data from a mysql database (select query) and also POST/PUT/DELETE for insert/update/delete rows in the database.
My question is now, is this not a big security issue if everybody is able to write or delete data in the database? But how could I prevent this, I thought the ST in REST stands for state transfer (so the webservice is stateless), which is a contradiction to a state like being logged in or not. And if I would pass some login data with the client which is allowed to write in the database, couldn't a bad guy catch the logindata and fake requests with it and for example delete all entries?
So, whats the normal way to go with this, the only Slim Framework examples I had found always show the route examples, but not how to secure it.
Are there also some opportunities in the Slim Framework to implement this what I need? It should be as easy as possible and the request should be responded nearly as quick as without an authentification or similar. There are no sensitive data like passwords, for me it would be enough that not everybody with a cURL commandline tool can delete all rows or things like that.
Would be great if anybody could explain me what to do and/or give some examples. I also need to know, what I maybe will need to change at the clients which are allowed to send the requests.
Lots of thanks.
Each request has to be authenticated and authorised.
People often get tied up with the word 'stateless'. This really just means that from one request to the next, the RESTful service has no prior knowledge of the users state.
BUT, the service is obviously allowed to be aware of the authenticated user that has just made a request, else how would it decide if it should allow access?
Therefore, you can 'store' the authenticated user in some variable during each request. Then it's up to you how you use this information to authorize the request.
I like to keep it simple and have all my users as a resource in my URI chain. They make requests like users/{username}/someresource.
I authenticate using http basic authentication (over SSL) and authorise based on the URI. If the request failed authentication, its a 401 Unauthorized Request. If the URI {username} and authenticated {username} do not match, the request is a 403 forbidden. If it is authenticated and authorized, the request is allowed (http code dependant on http verb)
Now that's the web service covered, now on to the web service client. This of course HAS to store state, otherwise your user would have to log in every time they make a request.
You simply store the users session in the application (as per normal session management) with the addition that you store the username and password (encrypted of course) in the session. Now every time a request is made, your web service client needs to retrieve the username and password, and send it with the request to your web service.
It will be stateless, in the sense that there won't be a session or a cookie, really. You'd normally issue out a key that would be required for INSERT/UPDATE/DELETE.
It is then up to you to pass the key with each request and to determine when a key should expire.
It would be as safe as normal http authenticated sessions. These use a cookie etc to authenticate the connected user to the stored session state.
A stateless service would be no different - the token is passed to the service just as a token is stored in a cookie for normal http. If you are worried about sniffing (IE man in the middle attacks) you would secure the link via SSL.
The authentication token generated by the service would be encrypted and would include a salt which is also verified on the server for each request. You could also limit the session time to suit your paranoia, and also check changes in source IP, user agent etc and expire the user's token if these change.
I recently ran into similar problem. As recommended by people here, I have decided to go with OAuth Authentication.
I am using HybridAuth A php wrapper for OAuth and out of the box sign in solution for Facebook, Twitter, Google, LinkedIn, etc.