views:

130

answers:

2

I've built a Single-Sign-On system for our web network. It works like this:

  • User clicks a login link on the site he wants to log in to (the "Unsafe Site"). The unsafe site's ID is passed in the URL.
  • He ends up on the system's (called "RAS") login page. This is on it's own domain, and may in the future get HTTPS, so the user can see his data is secure.
  • The user logs in. A "session" is made on the server which holds the user ID, the unsafe site ID and an expiry time.
  • The user's browser is redirected back to the unsafe site. The ID of the newly created session is passed as an URL parameter.
  • The unsafe site sends a request for the user's data to RAS. It includes the session ID and some credentials which will identify and authenticate the unsafe site on RAS. (Note that the user and his browser are left completely out of this)
  • The users's data (without the password) is returned to the unsafe site. The unsafe site then stores this in it's own session, or whatever, it doesn't matter.

(to see it in action, go to e.g. cncguild.net and click the login link near the top)

As you can see, this is pretty secure. At no point does the unsafe site have access to the user's password.

However, regarding usability, we'd like to better integrate the login process with the unsafe sites. The way to do this is to, instead of doing the whole "send to login page and redirect back", open up a popup of sorts. I currently see three possible method to do this:

  • Add an overlay div with the login form. Use AJAX to communicate with RAS until the login is complete and the client-side code receives the session ID. It can then handle the getting of the user data by sending this session ID to it's own server-side code (through a refresh or AJAX). While this would result in the best usability, there are some huge security pitfalls:

    • The unsafe site's Javascript has access to the password
    • While the user can check the source to see if it tries to steal it, who seriously does that?
  • Instead of putting the form in the same HTML document, let the overlay div contain an iframe with the login page.

    • This hides the password from the unsafe site (if the browser has decent iframe Javascript security policies)
    • There are no obvious browser interface markers to show the user that it's so. A malicious unsafe site author could therefore construct his own copy of the login form that looks exactly the same, but is not actually in an iframe.
    • There is no way to communicate the session ID back to the unsafe site except for a refresh. No fancy AJAX logging in on the unsafe site possible.
  • Opening the login page in a real popup (window.open)

    • URL and HTTPS icon are clearly displayed
    • It can be real ugly. I'm not sure if the usability does actually benefit a lot relative to the way it works now.

What are your opinions on each of these three options? Of course, I expect ridicule of the first option. It rips the security to pieces. I've included it for completeness' sake. More options are also welcome

A: 

Re

  • He ends up on the system's (called "RAS") login page. This is on it's own domain, and may in the future get HTTPS, so the user can see his data is secure.
  • The user logs in. A "session" is made on the server which holds the user ID, the unsafe site ID and an expiry time.

If the user is sending a password to the RAS login page, it needs to use HTTPS unless all machines on that network are trusted.

Is the user ID cryptographically strong and sent via HTTPS? If not, then what stops one untrusted (unsafe?) site from guessing another site's user ID and requesting the data?

Re:

  • The user's browser is redirected back to the unsafe site. The ID of the newly created session is passed as an URL parameter.

What stops this URL parameter from showing up in referrer headers sent to a third site if the user clicks on a link on the resulting page?

Re:

A malicious unsafe site author could therefore construct his own copy of the login form that looks exactly the same, but is not actually in an iframe."

You're not going to be able to solve the trusted path problem in HTML no matter what you do. Setting up phishing domains is too easy. The only way to get trusted path is by using an authentication protocol that has it built in, e.g. HTTP AUTH. This post http://www.eros-os.org/pipermail/cap-talk/2009-February/012249.html talks about trusted path mechanisms for web applications.

Re:

  • There is no way to communicate the session ID back to the unsafe site except for a refresh. No fancy AJAX logging in on the unsafe site possible.

There are many ways of communicating small amounts of data cross frame. Would one of the schemes listed on http://ajaxian.com/archives/crossframe-a-safe-communication-mechanism-across-documents-and-across-domains fit your needs?

Mike Samuel
The session ID is not secured, but that doesn't matter. The server knows which unsafe site can access it. The unsafe site, when requestion the user data, authenticates with an ID and a secret key. This requestion of data is from server to server (the client is not involved).
Bart van Heukelom
Ok, so you've got a signature or some other way for the unsafe site to prove its identity?And the channel between your server and the unsafe site is encrypted?
Mike Samuel
We are now actively working on getting HTTPS for our system so the channel between the 2 servers will indeed be secured (with a side note that at the moment the 2 servers are in fact 1).
Bart van Heukelom
+1  A: 

It trust and security are paramount, I wouldn't do an integrated login at all.

I expect that whatever domain name I see in the address bar is the entity that I'm sending my password to. In this case, if I don't trust the unsafe site, I won't login to it regardless of whether they claim to be using your SSO system, which I might otherwise trust.

That's why the OpenID model is popular. It federates login by redirecting the browser. This keeps the end-user aware and in control of what's going on. The end-user can then decide to login based on the trust they have in the OpenID provider whose domain name appears in the address bar.

gWiz