external.Default authentication plugin only considers leftmost part of the REMOTE_USER split by "@"
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
OpenStack Identity (keystone) |
Fix Released
|
High
|
Dolph Mathews | ||
OpenStack Security Advisory |
Invalid
|
Undecided
|
Unassigned | ||
OpenStack Security Notes |
Fix Released
|
Undecided
|
Nathan Kinder |
Bug Description
Hi there.
Keystone allows the usage of external authentication. This external
authentication makes possible for the deployers to integrate external
euth methods in Keystone. When it is executed as a WSGI application
(for example when executed behind apache using mod_wsgi) the
authentication can be made by the web server and the user will be
passed down using the REMOTE_USER environment variable. It is also
possible to use external authn by creating a custom WSGI filter that
will be pipelined. More details of this behaviour can be seen in [0].
[0] http://
Since the Havana release, this code has been refactored and moved to a
pluggable mechanism under keystone/
not wrong, this was introduced in commit
88c319e6bce9808
stable/havana since that commit, and is currently in the trunk.
[1] https:/
During the review of [2] the ExternalDefault plugin I've realized that
the way the plugin extracts the username can lead to impersonation.
The excerpt of code that extracts the username is this one [3]:
names = remote_
username = names.pop(0)
domain_id = CONF.identity.
user_ref = auth_info.
When Keystone is configured to use the defualt domain, the REMOTE_USER
variable is splited by all the "@" and then only the leftfmost part is
considered, while the leftovers are discarded. Since a username can
contain "@" inside (for example when emails are used as usernames)
"john" "<email address hidden>" and "<email address hidden>" will all get a token
belonging to the "john" user.
[2] https:/
[3] https:/
External authentication opens the door for any deployer to use any
authentication mechanism. OpenStack does not ship any external
authentication mechanism, but it is perfectly possible to use emails
as the usernames (or usernames containing "@", as X509 certificate
DNs). For example, a LDAP directory could be configured in Apache to
let the users in, and set the REMOTE_USER as the username, instead of
the user DN.
It is possible to easily reproduce this using devstack as follows:
ubuntu@
> ENABLED_
> APACHE_
> EOF
ubuntu@
(...)
ubuntu@
ubuntu@
+--
| id | name | enabled | email |
+--
| dc90b499a1c0499
| 685cd73e645243c
+--
ubuntu@
+--
| id | name | enabled |
+--
| d5319bc5b7054e0
| badfa689e32a4d9
| 110627ae8c534b5
| 92484643deb246e
+--
ubuntu@
+--
| Property | Value |
+--
| description | |
Listen 5000
| enabled | True |
Listen 5000
| id | 3ac4e3f06a35483
| name | external_users |
+--
ubuntu@
+--
| Property | Value |
+--
| email | |
Listen 5000
| enabled | True |
| id | a8fe063e8a124f8
| name | john |
| tenantId | d5319bc5b7054e0
+--
ubuntu@
+--
| Property | Value |
+--
| email | |
| enabled | True |
| id | 6af78b4bdca646a
| name | john@external_
| tenantId | 3ac4e3f06a35483
+--
So far I've two different users. For the shake of simplicity I will
use Apache's basic authentication, so it is needed to add the
following excerpt to /etc/apache2/
Listen 5001
<VirtualHost *:5001>
ErrorLog /var/log/
LogLevel debug
CustomLog /var/log/
<Location />
Require valid-user
</Location>
</VirtualHost>
And then, create the external user, and authenticate with it:
ubuntu@
New password:
Re-type new password:
Adding password for user john@external_
ubuntu@
* Restarting web server apache2
* ... waiting
ubuntu@
ubuntu@
% Total % Received % Xferd Average Speed Time Time Time Current
100 1134 100 1095 100 39 2301 81 --:--:-- --:--:-- --:--:-- 2300
{
"token": {
{
}
],
},
},
{
}
],
"user": {
},
}
}
}
As you can see, I am getting the id for the user "john"
(a8fe063e8a124f
"john@example_
in [2] should fix this issue (although it was initially unrelated)
since it does not split the username when using the ExternalDefault
plugin.
summary: |
- ExternalDefault authentication plugin only considers leftmost part of + external.Default authentication plugin only considers leftmost part of the REMOTE_USER splited by "@" |
summary: |
external.Default authentication plugin only considers leftmost part of - the REMOTE_USER splited by "@" + the REMOTE_USER split by "@" |
Changed in ossa: | |
status: | Incomplete → Invalid |
information type: | Private Security → Public |
tags: | added: security |
Changed in keystone: | |
assignee: | nobody → Alvaro Lopez (aloga) |
status: | Triaged → In Progress |
Changed in keystone: | |
assignee: | Alvaro Lopez (aloga) → Adam Young (ayoung) |
Changed in keystone: | |
assignee: | Adam Young (ayoung) → Dolph Mathews (dolph) |
Changed in keystone: | |
milestone: | none → icehouse-2 |
status: | Fix Committed → Fix Released |
Changed in keystone: | |
milestone: | icehouse-2 → 2014.1 |
Trying to determine whether this merits an advisory... can you expand on your scenario above? When you suggest "an external
plugin that uses the email as the username" is this common/recommended practice? Also, what releases contain code vulnerable to this?