Authentication integration: Difference between revisions

From OpenHatch wiki
Content added Content deleted
imported>Paulproteus
No edit summary
imported>Paulproteus
No edit summary
 
(6 intermediate revisions by 3 users not shown)
Line 1: Line 1:
{{Hacking OpenHatch}}
== Purpose ==
== Purpose ==


Line 4: Line 5:


This is necessary because the OpenHatch website is comprised of a few pieces. We do most of our work on the OpenHatch codebase in Django, but there's also this wiki and the bug tracker (and we're adding a forum). Users have asked for login integration.
This is necessary because the OpenHatch website is comprised of a few pieces. We do most of our work on the OpenHatch codebase in Django, but there's also this wiki and the bug tracker (and we're adding a forum). Users have asked for login integration.

Specific goals:

* Users only have to authenticate once to all (web) services within openhatch.org.
* Simple implementation.
* Users can't impersonate other users.
* Even if the forum is compromised, it's not totally trivial for the forum admin to impersonate OpenHatch users to other openhatch.org applications (especially openhatch.org itself).
* Applications outside openhatch.org should not be able to use this system to gain information about users. (They might be able to use ''other'' mechanisms, but not this one.)
* These applications don't have to be particularly securely maintained. (Specifics...?)

m_stone's notes:

* I'm a bit nervous about having splittable cookies. Maybe add an index cookie? (fun link: [http://wiki.laptop.org/go/Canonical_JSON canonical json])
* I'm a bit nervous about the inter-app dataflow that these cookies represent. How are you going to avoid exposing XSS opportunities in the apps receiving data through these cookies?
* Other minor nits: unicode canonicalization, redirect_to abuse & replay


== Overview ==
== Overview ==


Django code creates domain cookies within openhatch.org that contain the user's username and email address. The application (like the wiki) can read that information and verify it using HMAC-SHA1.
Django code creates domain cookies within openhatch.org that contain the user's username and email address. The application (like the wiki) can read that information and verify it using HMAC-SHA1.

== Before using ==

Every new application that gets added to the authentication integration system needs a key to use with HMAC.

To generate such a key, run this on '''linode.openhatch.org''' as the '''deploy''' user:

$ dd if=/dev/urandom bs=1M count=1 | sha1sum

That will output a hex string on its last name. We need to store that in the Django configuration, so we add that to '''deployment_settings_settings_secret_keys.py''' by adding a line like this:
AUTHENTICATION_INTEGRATION_KEYS['forum'] = '51996f577251de19efbd623a9c5045a9d4144415'

We need to then make sure the forum uses that key, too.


== Details ==
== Details ==
Line 13: Line 43:
=== Application: redirect ===
=== Application: redirect ===


If the wiki detects an OpenHatch session cookie, it redirects the user to http://openhatch.org/+create_user_data_cookie?redirect_to=http://openhatch.org/wiki/handle_login.php
If the wiki detects an OpenHatch session cookie, it:

* Creates a cookie called '''user_data__application__come_back_to''' and stores a URL in there
* Creates a cookie called '''user_data__application__come_back_to__hmac''' containing the HMAC-SHA1 of the come_back_to cookie
* Creates a cookie called '''user_data__application''' and sets it to a string that identifies HMAC key
* Redirects the user to https://openhatch.org/+create_user_data_cookie


=== Django code: create_user_data cookies ===
=== Django code: create_user_data cookies ===

The Django code creates a JSON object with the following keys:
* username: The username of the currently logged-in user.
* email: The ...


The OpenHatch site creates some cookies. All cookies contain text. We encode it as UTF-8 and then wrap that in base64.
The OpenHatch site creates some cookies. All cookies contain text. We encode it as UTF-8 and then wrap that in base64.




The "message" that we HMAC is the final, base64-encoded data.
The "message" that we HMAC is the final, base64-encoded data.


* '''user_data__email_address''': This contains the user's email address.
* '''user_data__json''': This contains the user's email address.
* '''user_data__email_address__hmac''': This contains a HMAC-SHA1 to verify the authenticity of the email address.
* '''user_data__email_address__hmac''': This contains a HMAC-SHA1 to verify the authenticity of the email address.
* '''user_data__username''': This contains the user's username.
* '''user_data__username''': This contains the user's username.
* '''user_data__username__hmac''': This contains a HMAC-SHA1 of the username.
* '''user_data__username__hmac''': This contains a HMAC-SHA1 of the username.

Finally, it checks for a '''user_data__application__come_back_to''' cookie. If passes the HMAC-SHA1 check, it redirects the user to that URL. Otherwise, it redirects the user to https://openhatch.org/.


=== Application: Read cookie data, then delete cookies ===
=== Application: Read cookie data, then delete cookies ===
Line 32: Line 75:
It should delete the user_data__* cookies that it read, to avoid keeping clutter in the user's browser.
It should delete the user_data__* cookies that it read, to avoid keeping clutter in the user's browser.


That's up to the application. It '''MUST''' verify the user_data__* using HMAC-SHA1 before trusting it, as users can tamper with this data.
It '''MUST''' verify the user_data__* using HMAC-SHA1 before trusting it, as users can tamper with this data.


The application should make its own "logged in" status expire at the end of the session.
The application should make its own "logged in" status expire at the end of the session.
Line 44: Line 87:
** We can fix this by constraining usernames on the Django side to be case-insensitively unique.
** We can fix this by constraining usernames on the Django side to be case-insensitively unique.
*** Right now, Django usernames [http://code.djangoproject.com/ticket/2273 seem to be case sensitive].
*** Right now, Django usernames [http://code.djangoproject.com/ticket/2273 seem to be case sensitive].

* me_stone says, "You should plan to rotate authenticators [keys for the hash]."
** Asheesh says, "Okay, fine. We should revisit this in September, 2011, and probably rotate them. (That's one year from now.)"


Some usability issues:
Some usability issues:
Line 52: Line 98:


* If an account gets deleted within the OpenHatch Django app, we don't have a way to ask downstream applications to delete their account of the same name.
* If an account gets deleted within the OpenHatch Django app, we don't have a way to ask downstream applications to delete their account of the same name.

[[Category:Hacking_OpenHatch]]

Latest revision as of 19:39, 4 November 2010

This is a page about improving or modifying OpenHatch.

We call that "Hacking OpenHatch," and there is a whole category of pages about that.

Purpose

If a user arrives at the OpenHatch wiki, and that user is already logged into the OpenHatch website, the wiki should have a way to identify the user and log the user in with the same username. This page describes a protocol for the wiki (and other applications within the openhatch.org domain) to ask the openhatch Django code for information on the current user (specifically, username and email address), receive that information, and automatically log that user in.

This is necessary because the OpenHatch website is comprised of a few pieces. We do most of our work on the OpenHatch codebase in Django, but there's also this wiki and the bug tracker (and we're adding a forum). Users have asked for login integration.

Specific goals:

  • Users only have to authenticate once to all (web) services within openhatch.org.
  • Simple implementation.
  • Users can't impersonate other users.
  • Even if the forum is compromised, it's not totally trivial for the forum admin to impersonate OpenHatch users to other openhatch.org applications (especially openhatch.org itself).
  • Applications outside openhatch.org should not be able to use this system to gain information about users. (They might be able to use other mechanisms, but not this one.)
  • These applications don't have to be particularly securely maintained. (Specifics...?)

m_stone's notes:

  • I'm a bit nervous about having splittable cookies. Maybe add an index cookie? (fun link: canonical json)
  • I'm a bit nervous about the inter-app dataflow that these cookies represent. How are you going to avoid exposing XSS opportunities in the apps receiving data through these cookies?
  • Other minor nits: unicode canonicalization, redirect_to abuse & replay

Overview

Django code creates domain cookies within openhatch.org that contain the user's username and email address. The application (like the wiki) can read that information and verify it using HMAC-SHA1.

Before using

Every new application that gets added to the authentication integration system needs a key to use with HMAC.

To generate such a key, run this on linode.openhatch.org as the deploy user:

$ dd if=/dev/urandom bs=1M count=1 | sha1sum

That will output a hex string on its last name. We need to store that in the Django configuration, so we add that to deployment_settings_settings_secret_keys.py by adding a line like this:

AUTHENTICATION_INTEGRATION_KEYS['forum'] = '51996f577251de19efbd623a9c5045a9d4144415'

We need to then make sure the forum uses that key, too.

Details

Application: redirect

If the wiki detects an OpenHatch session cookie, it:

  • Creates a cookie called user_data__application__come_back_to and stores a URL in there
  • Creates a cookie called user_data__application__come_back_to__hmac containing the HMAC-SHA1 of the come_back_to cookie
  • Creates a cookie called user_data__application and sets it to a string that identifies HMAC key
  • Redirects the user to https://openhatch.org/+create_user_data_cookie

Django code: create_user_data cookies

The Django code creates a JSON object with the following keys:

  • username: The username of the currently logged-in user.
  • email: The ...

The OpenHatch site creates some cookies. All cookies contain text. We encode it as UTF-8 and then wrap that in base64.


The "message" that we HMAC is the final, base64-encoded data.

  • user_data__json: This contains the user's email address.
  • user_data__email_address__hmac: This contains a HMAC-SHA1 to verify the authenticity of the email address.
  • user_data__username: This contains the user's username.
  • user_data__username__hmac: This contains a HMAC-SHA1 of the username.

Finally, it checks for a user_data__application__come_back_to cookie. If passes the HMAC-SHA1 check, it redirects the user to that URL. Otherwise, it redirects the user to https://openhatch.org/.

Application: Read cookie data, then delete cookies

Now it's time for the application (e.g., the wiki) to read the user data and log the user in.

It should delete the user_data__* cookies that it read, to avoid keeping clutter in the user's browser.

It MUST verify the user_data__* using HMAC-SHA1 before trusting it, as users can tamper with this data.

The application should make its own "logged in" status expire at the end of the session.

Known issues

There are some problems with this setup. Some security issues:

  • Email addresses and usernames travel along the network unencrypted. (In practice, this is no worse than the status quo, since session IDs already do that.)
  • Not all applications treat usernames as case-sensitive. This might allow an attacker to create a new username that is treated as equivalent to a different user, effectively stealing an account.
    • We can fix this by constraining usernames on the Django side to be case-insensitively unique.
  • me_stone says, "You should plan to rotate authenticators [keys for the hash]."
    • Asheesh says, "Okay, fine. We should revisit this in September, 2011, and probably rotate them. (That's one year from now.)"

Some usability issues:

  • The first time the user goes to the forum, the browser will redirect a few times. That'll be weird.

Missing features:

  • If an account gets deleted within the OpenHatch Django app, we don't have a way to ask downstream applications to delete their account of the same name.