Flourish PHP Unframework
This is an archived copy of the forum for reference purposes

Simple SSO (Single Sign On) the flourish way

posted by mblarsen 9 years ago

I believe the flourish developers have great grasp on security issues and I feel safe using flourish on our sites.

However searching for a simple cross site sign on solution, I've stumbled upon the 1x1 pixel image technique, where you from one of the sites loads an image of one of the other sites and in the same process sets a cookie with an ID used to retrieve the session, making sure all sites uses the same session.

The flourish demo site and the getting started guide recommends setting a session dir to avoid session hijacking, making it impossible to use the above mentioned technique.

Do you have any recommendations, ideas for a SSO solution that goes hand-in-hand with flourish's high standards? I've seen mentions of CAS (http://www.jasig.org/cas), any others?

Note that we want to solve to things:

  1. Single Sign On
  1. Sharing a basket of products between sites (login not required)

Thanks,

I'm sorry if this post is out of topic.

No, this certainly isn't off topic. SSO is certainly a desirable thing to have for users, but it is definitely a complex subject. There are varying approaches to SSO, from just authenticating a user, to providing shared information about the user.

I can't say I'm familiar with the details of the 1x1 pixel technique. If your research indicates it should be secure, I wouldn't see any issue with sharing a session directory among 3 different sites. If you are running on a shared server, it may not be possible to allow three of the sites to access it, but not the rest of the sites on the box. You could use a database to store the session files, which would prevent other sites from accessing it.

posted by wbond 9 years ago

1x1 pixel technique goes something like this.

Site A, B, C.

User arrives at site A.

On site A you include, two images with a src from the two other sites B, C.

#!text/html
<img src='www.sitea.com/gfx/l.gif?id=ljfl3k4j2ds' />
<img src='www.sitea.com/gfx/l.gif?id=ljfl3k4j2ds' />

The id refers to the database of id the stored session. The image will serve a transparent 1x1 pixel image. But before doing so it will set a cookie containing the id.

If you get your hand on this id you can basically retrieve the session. Or are you saying that since the session is in db it should be safe enough since the session id can only be fetched of the local machine? (all sites have local access to the db)

Thanks

posted by mblarsen 9 years ago

For one argument against this technique, consider that browsers, ISP servers, SOHO routers, corporate proxy, and other things between your visitor and your server, can all cache your l.gif, and thus your authentication cookies which rely upon l.gif may become stale, or perhaps the image is recognized and blocked by a filter (maybe adblock?) because a 1x1 gif pixel is a known tracking technique called, "web bug".

Also consider that this technique may appear to be a cross-site attack to certain heuristic filters (noscript?).

The pixel will allow the "sibling" servers to access the cookie. Does this not mean you will have to configure the original cookie to permit its usage on these sibling domains? If you aren't careful, your cookie is vulnerable to real cross-site attack. You may even need to consider defending l.gif, as well; but blocking loading of the image by referrer isn't perfect, because http referrer can be forged.

I believe it would be safer and more reliable to use a system such as suggested by Aris, so the server at every domain is actually involved in authentication in its domain.

posted by whatrevolution 9 years ago

whatrevolution, thanks for your feedback.

You make very strong arguments, and I will certainly look more into a solution like the one Aris suggested. The fact that some entity between my visitor and I can cache or block the image, hindering the cookie setting code from being invoked, makes this technique unreliable to the useless, the moment image loading and ad blocking (and the likes) are enabled.

Regarding the cross scripting issues, please consider that the session id is encrypted using salt known by all "siblings" as well as tiny bit context encoded by a algorithm known by all "siblings".

I guess it comes down to the sensitivity of your data. If you are interested building a user-centric site, highly customized and/or private data. This approach is probably not the way to go. But if you implementing a feature that does little more than adding to the usability and the experience of a coherent universe, storing simple state data, that is not required to run the site, then this solution might be okay. It is simple and easy to implement.

Any thoughts?

posted by mblarsen 9 years ago

Effectiveness of salt depends upon the chosen algorithm(s), available entropy, an attacker's ability to discover and possibly control the entropy, and so on. Supposing that we know and then account for these things, by choice of appropriate implementation of the method you're asking about, it's ok to do this. However, I would posit that Aris' SAML suggestion fulfills your requirement just the same, and in a rather similar fashion (read the specs for Open ID), without using the cross-site/domain image technique. The cross-site/domain activity occurs in Open ID and related systems during the authentication cycle, and includes a server-to-server dialog that is more secure than what I am imagining the image technique to imploy.

posted by whatrevolution 9 years ago

Well, for all SSO and related issues (federation and so on) I think the better solution would always be to rely on an external provider. (The application I am currently working on relies on SimpleSAMLphp).

As for Flourish, surely there would be no problem writing a simple login page based on SimpleSAMLphp API, given that all it should do is -basically- to check the user authentication status and redirect to the identity provider.

My own approach is similar although a bit different, however: instead of a login page the application controller includes an authentication module which deal with all these tasks. On success, I use fAuthorization::setUserToken() to set an unique identifier for that user.

By the way, as far as fAuthorization::setUserToken() uses fSession, do I need to start fSession::open() by myself or could I rely it is really started somewhere?

posted by aris 9 years ago

Hi Aris, thanks for the input. I will definitely check it out.

With regards to fAuthorization::setUserToken(). It will automatically open the session if you have not already done so yourself.

posted by mblarsen 9 years ago

I keep digging into Flourish and I have to say that deeper I go on, more astounded I am by their features. :-)

As I told in the previous post, I'm using SimpleSAMLphp for SSO and federation support. I have modified my original design, however, to benefit from Flourish authorization features.

I'm using a front-controller approach for my application. This front controller is in charge to load, among others, initialization, authorization checks, business rules controllers and views. Current setup, albeit very simplified, is as follows:

  • In initialization, the login page is defined with fAuthorization::setLoginPage('/login');
  • In authorization, we do the following check:
If user is not authenticated
  a basic ACL is set to allow access to public pages only (this includes login)
Else
  the user ACL is set
  the user environment is set (language...) according to user attributes received from IdP (see later).
Finally, requireACL() checks whether or not the user is authorized to get the requested page.
  • The login page, on its side, deals only with SimpleSAMLphp API:
Instantiates the SSp object
If user is not IdP authenticated, 
  go to IdP for authentication
Else, 
  retrieve user attributes returned from IdP, 
  set user token 
  redirect to requested page.

(To be precise, actually it also checks for autoregistration, based in a permission flag returned by the SP side of SSp).

With this approach the application keeps neatly separated authentication (delegated in SSp through the login page) and authorization, for which the application relies in Flourish fAuthorization class.

As far as I know, fAuthorization::requireACL() redirects the user to login page in case he doesn't have the required permissions. However, it seems this behaviour would meet us in a vicious circle in the case a user is actually authenticated but he is looking for some unauthorized page, going from the requested page to login and back again to the page... I'm wondering if I would do better with a logic such as:

If not authorized by ACL:
   If not logged in:
     Go to login page for authentication
   else:
     Display some error message

Or maybe requireACL() could be modified somehow to deal with such a case (a flag to indicate whether or not it should go to login or just to return a FALSE result...).

Regards, A. .

posted by aris 9 years ago

It seems like your app should require the user is logged in, which will redirect them to the login page, but if they are logged in and don't have enough privileges, do something else.

fAuthorization::requireLoggedIn();
if (!fAuthorization::checkACL('read')) {
    // Handle this error some other way
}
posted by wbond 9 years ago

Hi Aris

I'm really interested to learn my about your approach. Could I ask you some questions by email?

mblarsen at gmail dot com.

posted by mblarsen 9 years ago