Common session among few websites on different domains - web-services

I want to make few webservices, all of them will require login/pass authorization. I want to keep them all sync (one login, one password to all services), but also I want to share session between them.
If user is log in to service A, and open service B its automatically log in to this same account on service B like in service A.
How this is usually implemented?

I would consider a database to support the sessions.
You could have a database record that holds key session information. If the database supports BLOB fields you could even hold more complex session data.
The record would have a "cookie thing" that the web service requests would present, the service implementation code would take that "cookie thing" and look in the database table(s) to see if a login event had correctly occurred recently.
(I say "cookie thing" because if it is a webservice it may not actually be a browser coming in).

This is called a distributed session, implementations vary per webserver.
For Tomcat: http://tomcat.apache.org/tomcat-6.0-doc/cluster-howto.html
For WebSphere: http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/index.jsp?topic=%2Fcom.ibm.websphere.nd.iseries.doc%2Finfo%2Fiseriesnd%2Fae%2Fcprs_persistent_sessions.html
You can also store persisted variable in a database, which may be easier in your case.

Related

How to protect web application from cookie stealing attack?

My web application's authentication mechanism currently is quite simple.
When a user logs in, the website sends back a session cookie which is stored (using localStorage) on the user's browser.
However, this cookie can too easily be stolen and used to replay the session from another machine. I notice that other sites, like Gmail for example, have much stronger mechanisms in place to ensure that just copying a cookie won't allow you access to that session.
What are these mechanisms and are there ways for small companies or single developers to use them as well?
We ran into a similar issue. How do you store client-side data securely?
We ended up going with HttpOnly cookie that contains a UUID and an additional copy of that UUID (stored in localStorage). Every request, the user has to send both the UUID and the cookie back to the server, and the server will verify that the UUID match. I think this is how OWASP's double submit cookie works.
Essentially, the attacker needs to access the cookie and localStorage.
Here are a few ideas:
Always use https - and https only cookies.
Save the cookie in a storage system (nosql/cache system/db) and set it a TTL(expiry).
Never save the cookie as received into the storage but add salt and hash it before you save or check it just like you would with a password.
Always clean up expired sessions from the store.
Save issuing IP and IP2Location area. So you can check if the IP changes.
Exclusive session, one user one session.
Session collision detected (another ip) kick user and for next login request 2 way authentication, for instance send an SMS to a registered phone number so he can enter it in the login.
Under no circumstances load untrusted libraries. Better yet host all the libraries you use on your own server/cdn.
Check to not have injection vulnerabilities. Things like profiles or generally things that post back to the user what he entered in one way or another must be heavily sanitized, as they are a prime vector of compromise. Same goes for data sent to the server via anything: cookies,get,post,headers everything you may or may not use from the client must be sanitized.
Should I mention SQLInjections?
Double session either using a url session or storing an encrypted session id in the local store are nice and all but they ultimately are useless as both are accessible for a malicious code that is already included in your site like say a library loaded from a domain that that has been highjacked in one way or another(dns poison, complomised server, proxies, interceptors etc...). The effort is valiant but ultimately futile.
There are a few other options that further increase the difficulty of fetching and effectively using a session. For instance You could reissue session id's very frequently say reissue a session id if it is older then 1 minute even if you keep the user logged in he gets a new session id so a possible attacker has just 1 minute to do something with a highjacked session id.
Even if you apply all of these there is no guarantee that your session won't be highjacked one way or the other, you just make it incredibly hard to do so to the point of being impractical, but make no mistake making it 100% secure will be impossible.
There are loads of other security features you need to consider at server level like execution isolation, data isolation etc. This is a very large discussion. Security is not something you apply to a system it must be how the system is built from ground up!
Make sure you're absolutely not vulnerable to XSS attacks. Everything below is useless if you are!
Apparently, you mix two things: LocalStorage and Cookies.
They are absolutely two different storage mechanisms:
Cookies are a string of data, that is sent with every single request sent to your server. Cookies are sent as HTTP headers and can be read using JavaScript if HttpOnly is not set.
LocalStorage, on the other hand, is a key/value storage mechanism that is offered by the browser. The data is stored there, locally on the browser, and it's not sent anywhere. The only way to access this is using JavaScript.
Now I will assume you use a token (maybe JWT?) to authenticate users.
If you store your token in LocalStorage, then just make sure when you send it along to your server, send it as an HTTP header, and you'll be all done, you won't be vulnerable to anything virtually. This kind of storage/authentication technique is very good for Single-page applications (VueJS, ReactJS, etc.)
However, if you use cookies to store the token, then there comes the problem: while token can not be stolen by other websites, it can be used by them. This is called Cross-Site Request Forgery. (CSRF)
This kind of an attack basically works by adding something like:
<img src="https://yourdomain.com/account/delete">
When your browser loads their page, it'll attempt to load the image, and it'll send the authentication cookie along, too, and eventually, it'll delete the user's account.
Now there is an awesome CSRF prevention cheat sheet that lists possible ways to get around that kind of attacks.
One really good way is to use Synchronizer token method. It basically works by generating a token server-side, and then adding it as a hidden field to a form you're trying to secure. Then when the form is submitted, you simply verify that token before applying changes. This technique works well for websites that use templating engines with simple forms. (not AJAX)
The HttpOnly flag adds more security to cookies, too.
You can use 2 Step Authentication via phone number or email. Steam is also a good example. Every time you log in from a new computer, either you'll have to mark it as a "Safe Computer" or verify using Phone Number/Email.

Limit concurrent sessions per user in WSO2IS

We are using WSO2 IS as our enterprise identity platform. One of our tenants must restrict the number of concurrent sessions per user for security reasons.
The expected behaviour is the following: when a user logs in, if he/she already has logged in previously and the session is still valid, the new session must overwrite the previous one, so the login ends ok and he/she gets logged out from the first device/browser. Summing up: the new session always invalidates the old one.
I've been researching sites like this or http://soasecurity.org/ searching for answers, but I couldn't find any.
I think that I need to store the WSO2 IS session id (the one that comes in the commonauthId cookie and gets stored in session cache/persistence store) in the user store, so I can check what's the current user session and log out the user if the cookie id and the store id don't match. But there are two main concerns:
Where do I store the user session id? My main user store is LDAP, but I'd like to avoid one extra attribute there, because it's shared with many other applications and promote changes like this could be difficult for many reasons. Is there any way to put this data into a secondary store?
What's the most appropiate extension point in WSO2 IS to add code for storing the session id in a user store? I've been looking through the authentication framework and found that the method concludeFlow in DefaultAuthenticationRequestHandler class is where new sessions are created when there isn't a previously cached one available. It seems a bit "tricky" to extend that method, but I couldn't find a better solution. Maybe you can customize the authenticator or the user store, but I think that's not a good point of extension inside the authentication flow, because the new sessions are created later, in the request handler.
Thanks in advance.
The WSO2 identity server actually doesn't care about the number of open sessions. IMHO the identity server is not the best enforcement point where to check for the open sessions. Once the user is already logged in, you don't have much control over the framework and the user assertions (or an Oauth token) are returned.
Where do I store the user session id?
If you enable the session persistence, the session information (user session, saml SP sessions, ...) are stored in the database. However - it is intended for internal use. If the user logs out or closes the browser, the records may be still there. There's no information about the user web session.
Just a hint - we've used a VPN proxy (Juniper SA as SP) and WSO2IS as IdP to enforce a unique user session (for a new session the old one is invalidated).
Have fun

Hiding MySQL Credentials in Application

I need to create an application for a company and they would like to have people login to the application to have different permissions to perform different tasks.
My initial idea was to create a MySQL database, hardcode the credentials into the application and have the application connect to the MySQL database. The MySQL database would then have a table called "users" which would store usernames, passwords and permissions. The application would then query the server and perform the authentication.
The biggest problem with this is having the MySQL credentials hard coded into the application. If the application gets into the wrong hands, they could do lots of damage to the MySQL database if they snoop around to find the credentials and start dropping tables.
So I thought of developing a server that acts as an interface for the MySQL Database. For example, the client application would connect to the Server via TCP, and the server connects to a MySQL database. That way the MySQL credentials are never exposed to end-users. However, this means I have to develop a server application which a) will be harder to maintain and deploy for my customer (as opposed to just setting up a MySQL Server) and b)Has potential to introduce more bugs since I have an additional system I need to make (which relates back to point a for deploying bug fixes, etc)
So I was thinking instead of having a table of users in the database and having the application connect directly to the MySQL server with hardcoded credentials, the end-user would be given actual MySQL user credentials in which they would enter into the application to connect to the MySQL server. This means if someone gets their hands on the application, they can't do any damage to the MySQL database, but there still remains the risk of an end-user giving their credentials to the wrong person.
What are the best ways to have a desktop application connect to a MySQL database? Are there any other solutions other than the 3 I have thought of, or do you have any thoughts on my solutions?
As #Perception noted. Your best bet here is to implement a web service in front of MySQL. You don't want unknown numbers of clients from unknown IP addresses all having access to your database.
It would be really easy to DOS attack you by tying up MySQL connections. Not to mention that you would very severely limit your ability to scale your backend service to meet the demands of an increased client base without having a web service in between.
The web service could also offer you the ability to control user authentication and authorization in any number of ways (user/pass combination, token-based access, OAuth access, etc.).
Where I work there are two practices I have seen:
Each entity (person, thing, or business (depending on level of granularity needed) accessing the database) has their very own credentials. This was used on an MSSQL and on a Rocket Universe database. This is mostly the retail and legacy software.
We host the application ourselves and use a separate authentication system for users. The database credentials are stored on our server where the application is hosted. The client knows nothing of the backing database. These are usually web apps and web services.
Something you could do that we have done is that many of our applications actually talk through a RESTful service that emulates the database in a way. The application itself has no access to the database. I would read the wikipedia article on restful services for more information. Our authentication is done using Nonce encoded HMAC requests where each user is given their very own key tied to their credentials.
Wrapping the database in a web service gives you a few possible advantages:
If you decide to change your database structure while keeping the same information, you might not even need to update the client applications, just the service.
Credentials never leave the server, your credentials remain safe so long as nobody gains access to your server. Security in general is increased.
If you do your service cleverly enough, you could even transfer much of the internal logic that would normally be client side onto the server, making updates and bugfixes virtually seamless to the client.
The disadvantages that I see:
It is one more thing to maintain
Your application is vulnerable to denial of service attacks, but since it is a database that's a possible problem anyway
If the server goes down, all the client applications go down, but again, still a problem anyway.
RESTful architecture: http://en.wikipedia.org/wiki/Representational_state_transfer
HMAC: http://en.wikipedia.org/wiki/Hash-based_message_authentication_code
Our HMAC system works like so:
User logs in using username and password to their local application.
The local application communicates to our authentication service and gets a "Session Key" and shared secret for that username and password.
Using the Session Key (which expires in a short period of time), the application creates an API Key (which lasts a long time) and stores it to the computer. The session key could be used instead of an API Key if the user is required to log in each time. We mainly did it this way for convenience for some programs. If the computer is not secure, the Session Key should be used only and no API key is stored on the local machine. Each time the user logs in, they get a new Session Key.
Each request to the database service is accompanied by a HMAC-signed nonce which the application gets from the authorization service based on the API key. After getting the nonce, the application signs it using the shared secret. These signed requests can only be used once since the web service (which the user could know nothing about) authenticates the request. Once the signed nonce has been authenticated server-side by seeing if hashing the nonce with that particular API/Session Key's shared secret results in the same digest, the nonce is marked expired and the request is granted.
The above is vulnerable to man-in-the-middle attacks if HTTPS is not used, so often people make a message based on the nonce and the URL being requested along with a timestamp and compute the HMAC on that. The server then recreates the message based on the URL, checks to see if the timestamp is within some bounds (+/- 4mins or something), and then authorizes the user based on that information.
To further granulate operations, we also have a role system which checks to see if the user who owns the Session/API Key has been given permission to request the thing that they were requesting. If they have the appropriate role, the request is granted.
Summary: Credentials are done user-by-user, the end user has no knowledge of the database, a web service wraps the database in a RESTful API, and a role based system is used to make permissions granular.
This is just a suggestion and I am not saying this is the best or only way to do this. This just happens to be how we have ended up doing it where I work.
Let's look at two ways of dealing with database:
Client directly connects database, and manipulate database
Server connects to database and provide interface for client to use
Considering your use case:
valid valid serial number or to store/read information about certain user
it can be designed in the following way to provide security. (I'm no expert in this)
Client directly connects database, and manipulate database
You don't have to use your admin to visit database, instead you create a user for client only, and limit user's access privilege to only viewing (certain data). And you can enforce security policy at database by changing privilege for this user.
you can consult MySQL :: MySQL 5.1 Reference Manual :: 6 Security for more info.
6.2 The MySQL Access Privilege System
6.3 MySQL User Account Management
Server connects to database and provide interface for client to use
You can use HTTP and provide interface to client to use. And only the backend connects to the database.
Something like RESTful API, there are many easy to use framework that provides authentication and authorization.
I don't think it's good idea to let client have direct access to database in your case. So if possible, the second option is better.
Also note that password based authentication is not ideal.

Securing REST API without reinventing the wheel

When designing REST API is it common to authenticate a user first?
The typical use case I am looking for is:
User wants to get data. Sure cool we like to share! Get a public API key and read away!
User wants to store/update data... woah wait up! who are you, can you do this?
I would like to build it once and allow say a web-app, an android application or an iPhone application to use it.
A REST API appears to be a logical choice with requirements like this
To illustrate my question I'll use a simple example.
I have an item in a database, which has a rating attribute (integer 1 to 5).
If I understand REST correctly I would implement a GET request using the language of my choice that returns csv, xml or json like this:
http://example.com/product/getrating/{id}/
Say we pick JSON we return:
{
"id": "1",
"name": "widget1",
"attributes": { "rating": {"type":"int", "value":4} }
}
This is fine for public facing APIs. I get that part.
Where I have tons of question is how do I combine this with a security model? I'm used to web-app security where I have a session state identifying my user at all time so I can control what they can do no matter what they decide to send me. As I understand it this isn't RESTful so would be a bad solution in this case.
I'll try to use another example using the same item/rating.
If user "JOE" wants to add a rating to an item
This could be done using:
http://example.com/product/addrating/{id}/{givenRating}/
At this point I want to store the data saying that "JOE" gave product {id} a rating of {givenRating}.
Question: How do I know the request came from "JOE" and not "BOB".
Furthermore, what if it was for more sensible data like a user's phone number?
What I've got so far is:
1) Use the built-in feature of HTTP to authenticate at every request, either plain HTTP or HTTPS.
This means that every request now take the form of:
https://joe:joepassword#example.com/product/addrating/{id}/{givenRating}/
2) Use an approach like Amazon's S3 with private and public key: http://www.thebuzzmedia.com/designing-a-secure-rest-api-without-oauth-authentication/
3) Use a cookie anyway and break the stateless part of REST.
The second approach appears better to me, but I am left wondering do I really have to re-invent this whole thing? Hashing, storing, generating the keys, etc all by myself?
This sounds a lot like using session in a typical web application and rewriting the entire stack yourself, which usually to me mean "You're doing it wrong" especially when dealing with security.
EDIT: I guess I should have mentioned OAuth as well.
Edit 5 years later
Use OAuth2!
Previous version
No, there is absolutely no need to use a cookie. It's not half as secure as HTTP Digest, OAuth or Amazon's AWS (which is not hard to copy).
The way you should look at a cookie is that it's an authentication token as much as Basic/Digest/OAuth/whichever would be, but less appropriate.
However, I don't feel using a cookie goes against RESTful principles per se, as long as the contents of the session cookie does not influence the contents of the resource you're returning from the server.
Cookies are evil, stop using them.
Don't worry about being "RESTful", worry about security. Here's how I do it:
Step 1: User hits authentication service with credentials.
Step 2: If credentials check out, return a fingerprint, session id, etc..., and pop them into shared memory for quick retrieval later or use a database if you don't mind adding a few milliseconds to your web service turnaround time.
Step 3: Add an entry point call to the top of every web service script that validates the fingerprint and session id for every web service request.
Step 4: If the fingerprint and session id aren't valid or have timed out redirect to authentication.
READ THIS:
RESTful Authentication
Edit 3 years later
I completely agree with Evert, use OAuth2 with HTTPS, and don't reinvent the wheel! :-)
By simpler REST APIs - not meant for 3rd party clients - JSON Web Tokens can be good as well.
Previous version
Use a cookie anyway and break the stateless part of REST.
Don't use sessions, with sessions your REST service won't be well scalable... There are 2 states here: application state (or client state or session s) and resource state. Application state contains the session data and it is maintained by the REST client. Resource state contains the resource properties and relations and is maintained by the REST service. You can decide very easy whether a particular variable is part of the application state or the resource state. If the amount of data increases with the number of active sessions, then it belongs to the application state. So for example user identity by the current session belongs to the application state, but the list of the users or user permissions belongs to the resource state.
So the REST client should store the identification factors and send them with every request. Don't confuse the REST client with the HTTP client. They are not the same. REST client can be on the server side too if it uses curl, or it can create for example a server side http only cookie which it can share with the REST service via CORS. The only thing what matters that the REST service has to authenticate by every request, so you have to send the credentials (username, password) with every request.
If you write a client side REST client, then this can be done with SSL + HTTP auth. In that case you can create a credentials -> (identity, permissions) cache on the server to make authentication faster. Be aware of that if you clear that cache, and the users send the same request, they will get the same response, just it will take a bit longer. You can compare this with sessions: if you clear the session store, then users will get a status: 401 unauthorized response...
If you write a server side REST client and you send identification factors to the REST service via curl, then you have 2 choices. You can use http auth as well, or you can use a session manager in your REST client but not in the REST service.
If somebody untrusted writes your REST client, then you have to write an application to authenticate the users and to give them the availability to decide whether they want to grant permissions to different clients or not. Oauth is an already existing solution for that. Oauth1 is more secure, oauth2 is less secure but simpler, and I guess there are several other solution for this problem... You don't have to reinvent this. There are complete authentication and authorization solutions using oauth, for example: the wso identity server.
Cookies are not necessarily bad. You can use them in a RESTful way until they hold client state and the service holds resource state only. For example you can store the cart or the preferred pagination settings in cookies...

Storing a session using cookies or http session variables for a scalable solution?

I have one web app which under the login process stores the userId in a http session variable(After confirmation of course!). I'm not using any session variables other than this one to retrieve information about the user. I don't know if this one is the most scalable solution for me yet. Do my server reserve any memory for this? Is it better to use cookies instead?
If you are using multiple application servers (now or in the future), I believe the http session variable is dependent to the server the user is on (correct me if I'm wrong), so in this case, you can find a "sticky session" solution that locks the user to a particular server (e.g. EC2's Load Balancers offer this: http://aws.amazon.com/about-aws/whats-new/2010/04/08/support-for-session-stickiness-in-elastic-load-balancing/ ).
I recommend using a cookie (assuming my logic above is right), but you should make sure you have some sort of security measure on that so users can't change their cookie and gain access to another user's account. For example, you could hash some string w/ a secret key and the user ID which you check server-side to confirm it has not been tampered with.