Another Horizon login page vulnerability to a DoS attack

Bug #1459628 reported by Paul Karikh
258
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Mirantis OpenStack
Fix Released
High
Aleksander Mogylchenko
6.1.x
Won't Fix
High
Paul Karikh
7.0.x
Fix Released
Critical
Aleksander Mogylchenko

Bug Description

Summary: Another Horizon login page vulnerability to a DoS attack

This bug is very similar to: https://bugs.launchpad.net/bugs/1394370
Steps to reproduce:
1) Setup Horizon to use db as session engine (using this doc: http://docs.openstack.org/admin-guide-cloud/content/dashboard-session-database.html). I've used MySQL.
2) Run 'for i in {1..100}; do curl -b "sessionid=aaaaa;" http://HORIZON__IP/auth/login/ &> /dev/null; done' from your terminal.
I've got 100 rows in django_session after this.

I've used MOS 6.1. Here is upstream bug: https://bugs.launchpad.net/horizon/+bug/1457551

Tags: horizon

CVE References

Paul Karikh (pkarikh)
Changed in mos:
assignee: nobody → Paul Karikh (pkarikh)
status: New → In Progress
importance: Undecided → Critical
milestone: none → 6.1
Revision history for this message
Paul Karikh (pkarikh) wrote :

I believe that the root of the problem is this line in django_openstack_auth:
user_id = request.session[auth.SESSION_KEY] (https://github.com/jtopjian/openstack_auth/blob/master/utils.py#L27)
This operations looks valid. But after this moment we have no chances to prevent creation session because django nandles all other stuff.

When DOA tries to get access to the request.session, django creates instance of User object (before this action it is an instance of SimpleLazyObject). After few operations, when django couldn't find session with proveded sessionId, it creates new session: https://github.com/django/django/blob/1.7c3/django/contrib/sessions/backends/db.py#L29

Right now looks like best place to make any changes is this line:
https://github.com/openstack/horizon/blob/stable/kilo/horizon/middleware.py#L93

We need to avoid accessing any request.user fields (to avoid making new instance). Now I'm trying to find a way to check if request created by anonimous user and do not affect other cases.

Also I've contacted with Horizon core developers (Lin Hua Cheng and Eric Peterson). They agreed that this is a different bug and searching a way to handle it too.

Paul Karikh (pkarikh)
tags: added: horizon
Revision history for this message
Paul Karikh (pkarikh) wrote :

Looks like now I've triaged our bug.

Here three steps:
1) Add
if request.path == '/auth/login/':
            return None

above this line https://github.com/openstack/horizon/blob/master/horizon/middleware.py#L93

2) Disable 'django.middleware.locale.LocaleMiddleware' in settings.py
3) Remove 'request.user.is_authenticated()' from this line: https://github.com/openstack/django_openstack_auth/blob/master/openstack_auth/views.py#L72

After this curl request from the bug description do not make horizon create a lot of sessions in database. And also it looks like as a user I can use Horizon normally: I can login and browse pages.

Despite I still think that it is a Django issue, maybe we could somehow skip localisation middlware for login page request. And add lines from steps 1 and 3 from my comment #6. Also we will need to remove language-related lines from this file: https://github.com/openstack/horizon/blob/stable/kilo/openstack_dashboard/dashboards/settings/user/views.py#L36
If so, our loss will not be so large. But this workaround still very dirty, as for me. So I'm going to continue research.

Revision history for this message
Paul Karikh (pkarikh) wrote :

I've contacted with openstack security team since we have the same bug in upstream. They requested help from one of django cores, who has already helped to fix previous similar upstream bug.
I'm adding temporary patch, wich fixes bug, but very dirty. We need to disable locale middleware, since it tries to access request.session object, which makes django to create new session.
Here the patch for DOA

Revision history for this message
Paul Karikh (pkarikh) wrote :

Here the patch for Horizon.

Timur Sufiev (tsufiev-x)
Changed in mos:
milestone: 6.1 → 7.0
Revision history for this message
Timur Sufiev (tsufiev-x) wrote :

Moving to 7.0 because we haven't SSL support in Horizon for 6.1 => no Horizon on public interface there.

Revision history for this message
Paul Karikh (pkarikh) wrote :

Finally with upstream cores we came to conclusion that is is Django bug and it was fixed in Django (in 1.8.3, 1.7.9, 1.4.21 versions).
In the upstream bug we came to conclusion with one of hrizon-cores that since it is django bug and since in upstream we cannot restrict user to use exact version of django, we just do nothing.
For MOS bug looks like we have to restrict user to use one of this versions: 1.8.3, 1.7.9, 1.4.21. But since 1.4.* is too old and 1.8.* is not supported in the Horizon yet, I suggest to use 1.7.9 version.

Revision history for this message
Timur Sufiev (tsufiev-x) wrote :

Changing the status here to public security because the relevant upstream bug has been already opened.

information type: Private Security → Public Security
Revision history for this message
Timur Sufiev (tsufiev-x) wrote :

According to the info from Roman Vyalov, mos-linux team is responsible for updating Django. Version 1.7.9 is desired for using together with Horizon in MOS 7.0.

Revision history for this message
Aleksander Mogylchenko (amogylchenko) wrote :

CVE-2015-5143 was fixed in python-django 1.6.1-2ubuntu0.9, which is included in Trusty security channel.

Revision history for this message
Timur Sufiev (tsufiev-x) wrote :
Timur Sufiev (tsufiev-x)
Changed in mos:
status: In Progress → Fix Committed
Revision history for this message
Oleksiy Butenko (obutenko) wrote :

verified on MOS 7.0 ISO 265
{"build_id": "265", "build_number": "265", "release_versions": {"2015.1.0-7.0": {"VERSION": {"build_id": "265", "build_number": "265", "api": "1.0", "fuel-library_sha": "4fdf3d6b070204366593012428395d173698678a", "nailgun_sha": "0dfcf73deb8ae99654f3da2ea95b7b68b9ee7273", "feature_groups": ["mirantis"], "fuel-nailgun-agent_sha": "d7027952870a35db8dc52f185bb1158cdd3d1ebd", "openstack_version": "2015.1.0-7.0", "fuel-agent_sha": "082a47bf014002e515001be05f99040437281a2d", "production": "docker", "python-fuelclient_sha": "9643fa07f1290071511066804f962f62fe27b512", "astute_sha": "e63709d16bd4c1949bef820ac336c9393c040d25", "fuel-ostf_sha": "582a81ccaa1e439a3aec4b8b8f6994735de840f4", "release": "7.0", "fuelmain_sha": "9ab01caf960013dc882825dc9b0e11ccf0b81cb0"}}}, "auth_required": true, "api": "1.0", "fuel-library_sha": "4fdf3d6b070204366593012428395d173698678a", "nailgun_sha": "0dfcf73deb8ae99654f3da2ea95b7b68b9ee7273", "feature_groups": ["mirantis"], "fuel-nailgun-agent_sha": "d7027952870a35db8dc52f185bb1158cdd3d1ebd", "openstack_version": "2015.1.0-7.0", "fuel-agent_sha": "082a47bf014002e515001be05f99040437281a2d", "production": "docker", "python-fuelclient_sha": "9643fa07f1290071511066804f962f62fe27b512", "astute_sha": "e63709d16bd4c1949bef820ac336c9393c040d25", "fuel-ostf_sha": "582a81ccaa1e439a3aec4b8b8f6994735de840f4", "release": "7.0", "fuelmain_sha": "9ab01caf960013dc882825dc9b0e11ccf0b81cb0"}

To post a comment you must log in.
This report contains Public Security information  
Everyone can see this security related information.

Other bug subscribers

Remote bug watches

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