I am writing a simple protocol for a basic chat program.
my question is: once the client has authenticated by providing username and password, should I also ask the client to provide a token in it's following packets? or is it sufficient to keep it's authentication status in a table at server and never expect the client to prove it till it disconnects and reconnects?
You should not demand for authentication for any further messages after client has given correct credentials. If your suspect, each and every message should contain authentication information, and in this implementation you need not to authenticate via "login" - just demand security information on each message.
After successful login, the only case you may demand user credentials is when updating the client's information (by client itself), which includes changing password and other "user" information. You must ask for password when "change password" request is initiated.
Ensure that authentication is having some encryption attached, so that no one can intercept the message. You may also have some key (like few bytes string), that you can validate for each incoming message to ensure the message is coming from correct client (this as per your original design, not for the alternate design I given in first paragraph).
Related
I want to build an in-app chat application without any login.
So, the user communicates with the program (the backend), not with other user. So, it's a chatbot.
My question is: How to identify the user? Should I just log the IP address? Or, should I generate a random ID on server? Or, should I just generate it on the client?
As I understand, the purpose of identifying the user is for the server to keep track of who is sending the chat message and to send back the response to the appropriate client (user). IP address can't be reliably used as a way of uniquely identifying the user because of numerous reasons (it is a separate topic). One example of it would be this - A small company routes all the outgoing traffic from its office network via a single router that has a single IP address. In this case, the requests coming from different employees of that company would have same IP address as detected by the chat server. So it can't distinguish between these users.
The idea of generating unique identifier on the server for each user can work. A UUID or a JWT or something similar can be used to generate the id when the user initiates the chat for the very first time. This ID needs to be passed back to the client so that clients (users) can send the subsequent chat messages using the same ID. Thus, in this model, the client would need to have a place to store this ID so that it can keep passing it back to the server in its chat messages. Now the problem can happen when the client loses this ID. How can we recover from this situation? The answer would be similar to the approaches being used when someone loses their password. There are several recovery mechanisms such as sending the reset link on the trusted email address or sending it on user's phone as a code or generating a recovery key which is different from the ID and emailing it out to the user which can later be used to reset the ID. Basically, there should be an alternate and secure way (recovery flow) to identify the user if the ID is lost.
If the ID is generated on the client side, that can also work as long as all the clients are able to generate the ID that is guaranteed to be unique. Clients can pass in the generated ID to the server and server can check if it is already used and send a retry message to the client if it finds that it is already used. Or if the clients are using some hardware that has unique serial number and that serial number can be used to generate the ID.
In either cases, all the requests must pass in the ID to the server so that server can do the identification.
Hope this helps!
Actors
Front-end (fat client-side Javascript application) which has Facebook access token.
Back-end which 100% relies on OAuth2 authentication. All requests need to be authenticated via Facebook.
To mutate user data on the back-end, I require user to be logged in via Facebook. Ideally, with every request, I would know the Facebook's user ID (the one that graph.facebook.com/me provides).
Question 1
Is there a way to get whatever graph.facebook.com/me returns to be signed, so I don't have to call Facebook to verify it with every request, nor store state in my backend?
Situation 2
If the answer to Question 1 is "no", it means I have to invent my own. I am thinking of the following:
The user sends the access token to the backend.
Backend calls token debug API, signs the result with my key, and sends back to the client.
Every time client does a request, it includes the previously-included blob.
Upon every incoming request to the backend, it verifies the signature, which, if matches, means that the request wasn't tampered with and I can trust it is coming from the previously-verified token.
Question 2
If I employ this scheme (sign the answer from Facebook and send it upon every request), how can I safely implement this? Are there resources I could read up which would tell me:
Things to be cautious about with this scheme.
Which signature algorithm to use, how to safely verify the signatures.
How to avoid common types of attacks and stupid mistakes.
Thanks!
It's not really clear what exactly you want to do, but I think you should have a look at the docs at
https://developers.facebook.com/docs/graph-api/securing-requests
Quote:
Graph API calls can be made from clients or from your server on behalf of clients. Calls from a server can be better secured by adding a parameter called appsecret_proof.
Access tokens are portable. It's possible to take an access token generated on a client by Facebook's SDK, send it to a server and then make calls from that server on behalf of the person. An access token can also be stolen by malicious software on a person's computer or a man in the middle attack. Then that access token can be used from an entirely different system that's not the client and not your server, generating spam or stealing data.
You can prevent this by adding the appsecret_proof parameter to every API call from a server and enabling the setting to require proof on all calls. This prevents bad guys from making API calls with your access tokens from their servers. If you're using the official PHP SDK, the appsecret_proof parameter is automatically added.
I'm doing some vulnerability check on Liferay by using Burpsuite.
Through burpsuite, i changed the Get: request and the cookie
Cookie: JSESSIONID=8415D05C1E66F72CE8803607B6FEC26B.node1; COOKIE_SUPPORT=true; USER_UUID="2n3duSU0cr8TgknmHzm8ghmRUS2LVJfx6zmuvGFspuY="; GUEST_LANGUAGE_ID=en_US; LFR_SESSION_STATE_2983586=1431672874448; COMPANY_ID=10154; ID=79307664464f436b414f657133626843444f577a65773d3d;
from one user to another. The page then loads as if the user is the other user which i copied the request from.
I tried checking for current user using ThemeDisplay, serviceContext.getUserId, request.getRemoteUser, but am unable to get the Real User before i "hacked" changes in the request.
How am I able to get the real user if the request parameters and coookies get altered?
If you (rightfully) can't trust the network connection between server and browser, just switch to https - problem solved. Whatever public information is exchanged can be faked in addition to the session cookie. If you only communicate on an encrypted channel, you'll need to have the attacker on the server or on the client machine. And all bets are off then anyway.
The session id cookie is http's way to communicate state between the browser and the server in an otherwise stateless protocol. If that can be spoofed, no other means of (also public) information can replace this pseudo-random number - so you'll need to keep it private.
Check this article and this Liferay App by yours truly on the issues of https as well as mixed mode (http/https). Spoiler alert: Mixed mode typically does not work. At least it doesn't solve the problem you expect it to solve.
I am developing several Web Services that will be accessed by a mobile application. I have several requirements:
Each user will need to sign in with their own User ID and Password (the same User ID and Password they use to sign into the website).
Every Web Service request will need to be authenticated to ensure that the request is coming from the mobile app(s).
Every Web Service request will need to authenticate the user, since there is user-specific fucntionality built in, and access will need to be blocked if the user's account is disabled.
Let's assume that OAuth is not an option.
In order to ensure that Web Service requests are coming only from the mobile app(s), I am planning to use HTTP Basic Authentication in IIS (the mobile app(s) will need to have a User Account setup in Windows Server and the mobile app will need to store the User Name & Password and pass these in the header).
Next is the User Authentication for each Web Service request. Would it be suitable to encrypt the User ID, Password, and some shared secret key (a "pepper", of sort) with AES-256, pass that encrypted string as a parameter with each request (over HTTPS, of course), and then decrypt and parse it on the server to authenticate? This is the existing plan, but something just doesnt seem right about it - like it's not "secure enough".
What else can I do to properly authenticate users for Web Service requests?
I recently went through this problem and asked opinions from a group of senior people about how they solve the problem. Opinions were varied, but one consistent feeling is that your level of security depends on the use case of your application. Are you doing online banking or storing medical records? Then your security needs may be quite high. Social networking? Maybe not so much.
Basic Authentication is generally fine when encrypted over SSL, ColdFusion works well with it. If you use Basic Auth, make sure to encrypt your traffic with 1024-bit keys or better. Don't authenticate every request with username/password - that's unnecessary. Authenticate the first request, set a session token, and rely on the session token for your identification of users.
Set a polling mechanism from the client to the server to keep the session alive - set the session timeout to 30 minutes and the polling frequency at 25 minutes, for example. Otherwise you may need to re-authenticate expired sessions. Again, how you approach this part of the solution depends on your paranoia level, which depends on what kind of data/app you are dealing with.
Cookies, and therefore sessions, should work fine in iOS apps. If you use sessions to verify identity after authentication, make sure your session cookies are memory-only (set at the server level).
Check the SSL implementation of your server against the Qualysis SSL Test:
https://www.ssllabs.com/ssltest/
The report will give you a surprising amount of detail about the strength of your SSL implementation.
Lastly, consider implementing two-factor authentication to combat password theft.
If you ignore the SSL advice and plan on encrypting your password and communicating over an insecure channel, look at the Kerberos protocol for a well-known example of how to authenticate securely:
http://en.wikipedia.org/wiki/Kerberos_%28protocol%29
Yes, you can use Basic Authentication but that means the client will need to store the username/password in plain text, and also send them over in plain text. Sending part is sort of fine if it's under HTTPS, but storing username/password in plain text may not be a good idea, unless you're using some secure key store.
Let's assume you have decided that Basic Authentication is the way to go, and you want to make use of the official CF way of supporting that, then you can use CFLOGIN.name & CFLOGIN.password. You may also check out Ask Ben: Manually Enforcing Basic HTTP Authorization In ColdFusion. In the remote cfc side, always validate the username/password, or return some sort of token and asks the client to use that token going forward. The token can be cfid+cftoken if you like, or even roll your own that never expires. If you use cfid+cftoken, and send them over as cookie or in body along with your web service call, I believe you can resume the session if you so choose.
I just started of in Django and want to implement this. But not sure whether my approach is correct or not. Can you validate?
Requirement : My Server will provide a service via an url endpoint. Client will authenticate (with id and password supplied to him via separate channel. So, no signup page available) with his credentials and avail the service. i will do the work asynchronously and reply with status.
My Approach.
. Client will be provided a username and password via separate channel.
. Client will do an https connection.
. Client will encrypt the password with my public Key and will call my URL endpoint with id, password, data.
. i will acknowledge the request and will ping client back when the work is done.
Things i am worried about:
. how to stop snoopers from replacing the data portion and reforwarding the request to me.
. how to stop snoopers from reusing the encrypted password from original request and sending their own request.
Are there any frameworks which will provide this support inbuilt?
OR
This will not occur at all in my current setup?
I know Django provides an authentication module. But not sure about its capabilities.
The framework will help you enable security at an application level. You can use Django to help you ensure that only users that have been properly authenticated will be granted access to restricted pages and provides a number of other security measures out of the box.
Replay attacks will typically be prevented by using sessions, which is well documented by Django.
Based on the description of your implementation, the greatest source of concern would be the statement "client will be provided a username and password via separate channel".