With default configuration Horizon is exposed to session-fixation attack

Bug #1327425 reported by Doug Fish
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Dashboard (Horizon)
Won't Fix
Undecided
Unassigned
OpenStack Security Advisory
Won't Fix
Undecided
Unassigned
OpenStack Security Notes
Fix Released
Medium
Travis McPeak

Bug Description

With the default configuration, if an attacker can obtain a sessionid value from a user, the attacker can view and perform actions as that user. This ability does not go away after the user has logged out.

To view a potential exploit:
1) Create an admin profile with access to the admin project and a non admin profile with no access to the admin project
2) Log in to Horizon as the admin, navigate to the project/instances page. Launch some vms.
3) Open up firebug and capture the sessionid value.
4) Log out of the admin user.
5) Log in as the non admin user
6) navigate to the project/instances page
7) Use firebug to past in the admin value of the session id value
8) click the project/instances link again to force a round trip.
*!* It's possible for the non admin user to view all of the admin project vms
9) In the action column choose More->Terminate Instance
*!* It's possible for the non admin user to delete an admin project vm.

Revision history for this message
Doug Fish (drfish) wrote :

Although I've marked this as private it does seem to be a well-known issue
http://www.pabloendres.com/horizon-and-cookies/

Revision history for this message
Grant Murphy (gmurphy) wrote :

This might be OSSN territory. It isn't something we would issue an advisory for IMHO.

Revision history for this message
Thierry Carrez (ttx) wrote :

Yes, I think it would make sense to issue a security note on that topic. The article by Pablo is a good read.
It's a well known issue so i'll make it public.

information type: Private Security → Public
Changed in ossa:
status: New → Won't Fix
Changed in horizon:
status: New → Won't Fix
Changed in ossn:
assignee: nobody → Travis McPeak (travis-mcpeak)
importance: Undecided → Medium
Revision history for this message
Travis McPeak (travis-mcpeak) wrote :

Does anybody know the steps that are required to configure Horizon to use memcache backend rather than signed cookies? I'm working on the OSSN, and want to test the solution to make sure it works.

Revision history for this message
Travis McPeak (travis-mcpeak) wrote :

I have tried simply changing the SESSION_ENGINE in settings.py to 'django.contrib.sessions.backends.cache' and restart apache2 and memcached services. Login seems to succeed, but the browser remains stuck on the login page.

Revision history for this message
Julie Pichon (jpichon) wrote :

Hi Travis,

You also need to change the "CACHES" dictionary to indicate where memcached lives (the commented out example in the local_settings.py file actually gives a Memcached example):

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}

Note that the local_settings.py would also be the expected place where to override the SESSION_ENGINE setting. Both CACHES and SESSION_ENGINE are Django settings, in case it'd be nice to also link back to the Django documentation in the note -

https://docs.djangoproject.com/en/1.6/ref/settings/
https://docs.djangoproject.com/en/1.6/topics/http/sessions/#configuring-sessions

Nathan Kinder (nkinder)
Changed in ossn:
status: New → In Progress
Revision history for this message
David Lyle (david-lyle) wrote :

I'm not sure this is the full characterization of the bug. As of https://github.com/openstack/django_openstack_auth/commit/b319ac78c81a2b0ad66fa998adf9347c4eec7ec0 the default behavior is to revoke the token when the user logs out. This works only with keystone v2 which was the default in the icehouse release but not the Havana release. Once the token is revoked actions like terminate instance should not work, if it does, that's a keystone bug.

My point is that there are nuances here that are not been spelled out in this bug. Current code https://github.com/openstack/django_openstack_auth/blob/master/openstack_auth/views.py#L108

I am certainly for documenting the issue where applicable.

Revision history for this message
Myles Hosford (myleshosford) wrote :

+1 with above comment.

This is a bug in that the session token is not terminated on logout - which has previously been raised as a bug and fixed. Changing the configuration to use memcache instead of the default session store does nothing to prevent an attacker obtaining and using the authenticated session token - if your using memcahce and I can steal your cookie (via unencrypted HTTP or XSS or any other method) I can still compromise Horizon.

From the OSSN:

### Discussion ###
When configured to use client side sessions, the server isn't aware of the user's login state. The OpenStack authorization tokens are stored in the session ID in the cookie. If an attacker can steal the cookie, they can perform all actions as the target user, even after the user has logged out.

--

Surely if the attacker steals the cookie (regardless if its using memchace) they can still access Horizon and impersonate the victim.

IMO the issue is that the session token is not terminated on logout; if that bug still exists - and nothing to do with how sessions are stored on the server?

Revision history for this message
Doug Fish (drfish) wrote :

Hey David - thanks for the insight. I'm glad to see the code that you've pointed out. I agree revoking the tokens is the proper solution. I'll study the behavior again and see if the code you've pointed out isn't behaving the way we expect, or if this is a keystone problem.

Myles - I think we all agree revoking the token is the ideal solution. However, I think there is greater impact not revoking the keystone tokens when client side cookies are being used. When using any server backed session (memcache, database, or whatever) when the user logs out the session is expired and having the cookie to reference the session is no longer of any value - the session has been removed from the server. The problem with cookie backed session storage is that even if the user has logged out, if an attacker had previously obtained the cookie its going to remain usable until the tokens sign out.

Still, just based on black box test testing I've been able to recreate the scenario I originally described with cookie based sessions, and haven't been able to with memcache or database backed sessions. Has anyone else verified that they can create this behavior? or attempted to recreate and found that keystone handles the problem correctly?

Revision history for this message
Myles Hosford (myleshosford) wrote :

Hi Doug,

This only addresses the timeout/not being invalidated on logout problem though right? I mean, when using memcache as the back-end does Django still set a sessionid cookie via the HTTP Set-Cookie Header during authentication? If yes - then this can still be compromised/obtained by an attacker (via unencrypted HTTP or XSS like the OSSN states) who can then go on to compromise Horizon in the way outlined above (pasting sessionid via firebug as long as it has not timed-out and is still valid).

Revision history for this message
Doug Fish (drfish) wrote :

Hi Myles,

You are correct, for all options there is a window of exposure of the sessionid cookie is exposed to an attacker.

The difference is that for all options other than signed cookies the exposure of the session data is closed once the user logs out. At user logout the session data is destroyed and any sessionid cookie that may have been obtained by an attacker is useless, because the corresponding session on the server no longer exists.

For signed cookies the "sessionid" is really the session data itself in encrypted form. If an attacker obtains it, this layer of protection (the http session is removed at logout/http session timeout) does not apply. The session data that we'd like to destroy is actually the cookie itself. In other words, the compromised session data will exist as long as the attacker cares to keep it.

Fortunately, as David has pointed out, Horizon has code that is supposed to call keystone to revoke the tokens at logout. It didn't seem to work in my case, so I'm still still investigating. So the idea with relying only on that code is that even though the session data might still be exposed, any tokens in the session data are revoked and (should be) useless.

Myles, I don't understand where you are leading with your questions. Are you suggesting that changing the configuration doesn't provide any significant additional security? or is there some other change that you'd suggest?

Revision history for this message
Myles Hosford (myleshosford) wrote :

Hi Doug,

Thanks for clearing that up. My initial comment was around the OSSN description, it seems to indicate that the fix will resolve the issue of using the session token if compromised. Il add a comment to the note.

Revision history for this message
Travis McPeak (travis-mcpeak) wrote :

Hi Myles,

To be clear, this bug is related to an attacker being able to use a session ID even after the user has logged out. Server side session tracking prevents this bug by terminating a session on logout. I have tested that the solution that I documented in the OSSN does prevent the session from being used after logout.

This bug doesn't have anything to do with preventing an attacker from capturing a session ID and using it to impersonate a user.

I have only tested this with Icehouse, so I'm not sure about Havana. I did get some feedback while writing the note that said it would be applicable to Folsom, Grizzly, and Havana as well, so I included those in the note.

Changed in ossn:
status: In Progress → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.