I am writing mobile client for online store. I have written REST API for accessing data on the server. Now I need to authentificate the user.
I have read a lot about this,and came to the simple solution.
Firstly, when user run application first time, he must enter exactly password and login from online store account. In this case password somehow sent to the server and being checked, after that user gets response.
If everything is OK user receives access toke that can be used in the future to access private data. If not, get simple forbid message.
I have some questions here :
What the best way to send password and login for the first time, to get access token. Encrypt password with some algorithm and than send it over simple HTTP or establish HTTPS session and simply use this channel to transfer data over the net. In this case password don't have to be encrypted, use public/private keys provided by HTTPS ?
Is it okey to send this request as POST method over HTTPS, for example using next URL /api/v0/store/auth ? Or it is better to do this another way.
In all cases where HTTPS is used I need self-signed certificate ?
I would be grateful for any help. Thanks in advance.
1 - it is not true that passwords don't have to be encrypted on HTTPS. The best approach would be your server encrypting the plain password just received and then try to authenticate the user, generating a token. This token should only last during this connection.
2 - yes, post method is okay for authentication.
3 - you may use self-signed certificates but if you do the client will probably trigger an alert because it won't recognize your certificate. The correct way should be aquiring a SSL certificate from an authorized provider like VeriSign and others.
Related
Let's say I have a MySQL database with thousands of user accounts in it. These accounts contain lots of data, but for verification purposes, they each contain a username and a (hashed and salted) password. Now, when a user requests signing in, I will take a username and password from them, transfer it via WSS to a Node.js server then transfer it via HTTPS to a PHP file on another server. On that server I will look up the username in the MySQL database, and if I find an account, I will hash the password and see if it matches that username's password. If they both match, then I want the PHP file to create a "verification token" of sorts, save it (and associate it with the account verified) and send the token back to the Node.js server. I then want the Node.js server to send that token back to the client and for the client to save that token. Now the next time the user connects to the Node.js server via WSS, I want the client to check for an existing token, and if it exists I want it to send that token via WSS to the Node.js server, the Node.js server to send that via HTTPS to a PHP file, and that PHP file to see what account that token belongs to, and complete the sign in...
So I guess my first question would be: Is this a good model? Would this be a good idea, and would this be secure, or should I do this differently?
My second question is: What would be the best way to go about generating this token? Should it be completely random? Should it be a combination of letters+numbers? Should it be a hash of some random values? How should I go about the generation of this "token"?
To clarify, I'm not asking how to build a server or make requests or transfer data or anything of that sort, I'm merely asking what is the most secure way to generate a "token" that can be used as authentication to the same degree that a username+password can be used.
Thanks in advance! I'm sorry if this is a really stupid question.
I think you are describing a JWT. There are several packages implementing this in PHP.
Does the following authentication system seem reasonable:
Client calls the login end point with a user name and password to the main server. The main server sends this off to another authentication server (which will receive no further mention), which returns a yes/no if this is valid and a user ID that the main server is aware of. If yes, generate a random token (using some crypto library that spits out random strings), and store the hash of this (using PHP's password_hash()) and an expiry 12 hours from now on the user record. Return the token to the client.
Client now adds "Authorization: Token TOKEN+HERE+ABCD1234" to their requests to other endpoints. The server ensures that the hash of the token in the auth header matches the one in the database (using salts through PHP's password_verify()), and that the expiry hasn't been hit. If it doesn't match, or the expiry is exceeded, then send back a 401.
Seems at least as secure as basic HTTP authentication, which just has the base-64 encoded user:password in the header? The reason I'm considering this scheme over basic is that the main server won't store the username/password that the authentication server is using to log in.
What am I forgetting? Is this grossly insecure?
Your scheme is not that different from the standard server-side sessions where SESSION-ID is normally nothing more than a random token and stored on the client side within a cookie, with 2 improvements:
Instead of a cookie you would use Authorization header to deliver the token. This acts as a CSRF protection.
You would hash a token on the server-side. This helps against session hijacking in case someone gets access to your token-store on the server-side.
If you see the oAuth process of Google then you will get idea of how Authorization works for them.
They have different servers for Authorization and API calls. User sends authentication details to Authorization server and receive a code. Google is having process of taking user consent to access details but you can skip this process to take consent and just return code on successful details.
This code can be further used to get the Access Token from the API server. So your first request to API server would be to get the Access Token. Google is having facility to refresh your Access Token as well.
And all subsequent request to API server must contain Access Token. So you seems to be missing this Code exchange process to make it more secure.
More info: https://developers.google.com/identity/protocols/OAuth2
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 developing an iphone app and I need to implement a 'safe' login system.
When the users writes his credentials, using a httprequest, phpmysql responds if authentification is correct or not.
But.. Do I have to send the credentials for every request after the login? For example: When I'm logged in, if I wanna get my profile info, should I send my credentials again?
I thought to implement a 'token' system, when an user logs in the server responds with a 'token' wich could be used for every request but... What if someone 'intercepts' this token? He could make petitions using this token like if he was the other user..
Hope I could explain what I'm trying to do (not using ssl)
Thanks!
You should encrypt the credentials before you transmit them using AES or a SHA512 hash. This goes for using the token as well if you go that route. Definitely use SSL.
You must use SSL/TLS (read: https) if you don't want someone to sniff your clear text credentials, whether it be token or any other credentials.
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.