I created a REST API and implemented a Signature system as a layer of security, basically how it works is that I have API users that connect to the API using a secret key(lets say a password) that only the user and the API know, then after a session is open the API return an API key to be used for all subsequent calls.
All subsequents call will provide the API key and a sha256 hash of the different request parameters, hash created using the secret key.
So far so good, however I am facing a problem where I have a full AJAX client calling the API, but I don't want my users to type their username and password(secret key) everytime they want to open a session and get a new API Key if they previously connected to the API in the past.
Temporarily, I am storing the secret key in plain text in a cookie using javascript but it seems wrong to me.
Do you guys have suggestions or links to point me too? Is there something I don't understand?
Thanks in advance!
Give them a hashed lease on the API. A lease grants them access to the API for a certain amount of time, and that time is specified in the token. For example, it could be good for the next 7 days. You can do this by simply adding the end date to your token and signing it.
When the app goes back to try and start a new session, it can ask the server to give it a new lease, assuming they're already authenticated, good for another 7 days.
If they try to access the server after 7 days, then they need to re-authenticate.
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 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..
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 designed APIs in php using SLIM framework. I can access these APIs like this:
http://192.168.1.210/getSchool
This API is used to get information about schools. I am using these APIs in my android application. Now I want to make security of my these APIs. so no one can access these APIs with out authentication means no one can get list of schools by just entering the above URL in address bar.
I want that user first log in using my android application then he or she can use my api, no one can directly access in my apis.
Please give me your valuable suggestion.
Thank you in advance.
Once a user is registered with your application, you can generate & assign them an API key in the database (perhaps a hash) which you can return to the phone. Each time the phone sends a request to the API it also sends across their API key which you can validate against their database entry.
This should also all be done over SSL to avoid MITM attacks/viewing of API keys.
There are also other methods available: Looking for suggestions for building a secure REST API within Ruby on Rails (language agnostic).
You should create UID and a secret key for each user when they sign up and store on the server. And pass these to the user using https initially. The user will store these two values(make sure secret key is kept safely).
When the user want to send a api request he will create the request url then hashes it using the secret key + timestamp and addes the UID, hash and timestamp to the request and sends to the server.
The server extract the UID then gets the secret from db and then generated the hash of the request (without UID, hash and timestamp) using secret key + timestamp param.
if the hash generated and the hash param from the url matches proceed with the request or ignore it.
Or
Implement OAuth
I am working on builing an API and application section on a social network so it will be something like myspace, facebook, hi5, friendster, netlog, and many other's have application section, they all use a REST server method and most of them will issue a api key and secret to each application developed. The person who builds the app will pass the api key and a user signature that is created with a hashing algorithm based on the user's ID who is using the app and the apps' API key. The applications code should set a cookie with some information like user id and signature and time. So on my server end the REST part should I just build the signature the same way the app does, check to make sure they are the same, if they are I send the correct data back. My concern is, how do I make sure a developer does not set a user's cookie to keep them authenticated for a long time, should I compare the time the users signature was created and if it is like a day old then I will send a bad response back from the REST?
When a user first add's an application from my main site, I will load the application site into an iframe and I will pass in user ID and other fields where I include the iframe so the application can use GET to initially get the information it needs to set it's cookie.
If you can help on this issue I would appreciate it, does it sound like I am in the right direction so far?
BTW I am using PHp/MySQL
I would store the token & user identifier that you pass back via the API in a database with a timestamp. When the user checks in via API to authenticate, check that timestamp and see if it is too old. If it is then pass back something like FALSE which would trigger some other command to make them re-authenticate into your system, which in turn would generate a new api token for the user to use.
Store a time() value in a session and every time the user does something check that time value to see if it's been longer than X minutes.