Domain Existence Leaking without authentication

Bug #1786646 reported by Morgan Fainberg
12
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Identity (keystone)
Won't Fix
High
Unassigned
OpenStack Security Advisory
Won't Fix
Undecided
Unassigned

Bug Description

The Domain Configuration subsystem, specifically PATCH /domains/{domain_id}/config/{group} appears to leak data before enforcement. The method called from the routed path[0] performs a "domain exists" check[1] before sending to the 'update_domain_config' method [2] which is behind the @protected decorator.

This has the potential to be used to verify existence of domains by ID without authentication. This is in-fact a data leak. However, since domains (outside of "default" and the keystone-root domain) are uuids, this is likely a C1 classification in the VMT Taxonomy [3] (Useful if an attacker is guessing UUIDs). The only case where this is more significant is that it can be used to determine if the default domain is enabled/configured; the usefulness of such data is relatively suspect and unlikely to be meaningful.

However, with all that said, since this is a potential security flaw, the bug has been marked private security.

[0] https://github.com/openstack/keystone/blob/c7ae6b798ad4b2164ed6248f1714ec44b27edb7a/keystone/resource/routers.py#L55
[1] https://github.com/openstack/keystone/blob/c7ae6b798ad4b2164ed6248f1714ec44b27edb7a/keystone/resource/controllers.py#L134
[2] https://github.com/openstack/keystone/blob/c7ae6b798ad4b2164ed6248f1714ec44b27edb7a/keystone/resource/controllers.py#L125-L131
[3] https://security.openstack.org/vmt-process.html#incident-report-taxonomy

Tags: security
Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

Since this report concerns a possible security risk, an incomplete security advisory task has been added while the core security reviewers for the affected project or projects confirm the bug and discuss the scope of any vulnerability along with potential solutions.

description: updated
Changed in ossa:
status: New → Incomplete
Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

Digging in further, it looks like we have a much wider spread set of related/similar issues. Either this bug can be expanded to cover it (becoming a VERY large C1 bug) or can be split out:

* The @protected/@filterprotected decorators do not have safety built in to prevent the .get_member_from_driver call from raising out an exception before enforcement is called. Most of the cases, this is not relevant, as we explicitly check if an entity exists in the code, but it might not in all cases. [1]

* @protected and @filterprotected do not wrap the callbacks in a try/except. This means that if the callbacks raise out a 404, they do so before enforcement calls are handled, so the 404 supersedes the 403 response, [2] calls [3], and runs the function/method with no protection[4]. An example of where this is explicitly shown is in the "add_user_to_group"[5], "check_user_in_group"[6]. and "remove_user_from_group"[7] (and I am sure there are more) - these are impacted because "_check_user_and_group_protection"[8] does not have a try/except in it.

[1] https://github.com/openstack/keystone/blob/4140652ec3043d064ccd4669c4b95b8b1b0e8151/keystone/common/authorization.py#L75
[2] https://github.com/openstack/keystone/blob/c59c660a105efe7fc5e74bbcd4b3c35c5e07f47c/keystone/common/controller.py#L76
[3] https://github.com/openstack/keystone/blob/c59c660a105efe7fc5e74bbcd4b3c35c5e07f47c/keystone/common/controller.py#L80
[4] https://github.com/openstack/keystone/blob/c59c660a105efe7fc5e74bbcd4b3c35c5e07f47c/keystone/common/controller.py#L146
[5] https://github.com/openstack/keystone/blob/c59c660a105efe7fc5e74bbcd4b3c35c5e07f47c/keystone/identity/controllers.py#L102
[6] https://github.com/openstack/keystone/blob/c59c660a105efe7fc5e74bbcd4b3c35c5e07f47c/keystone/identity/controllers.py#L108
[7] https://github.com/openstack/keystone/blob/c59c660a105efe7fc5e74bbcd4b3c35c5e07f47c/keystone/identity/controllers.py#L113
[8] https://github.com/openstack/keystone/blob/c59c660a105efe7fc5e74bbcd4b3c35c5e07f47c/keystone/identity/controllers.py#L41-L46

Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

This all still appears to require guessing UUIDs, no direct wide-spread data leaking without knowledge of the uuid or a wild guess. I would classify this as a very large surface area C1 (at the moment)

Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

For Stein (current master), the fix is largely covered in the FLASK conversion(s) as I'm addressing the C1 concerns as the APIs are ported to flask.

Revision history for this message
Gage Hugo (gagehugo) wrote :

I can recreate the issue in the main description as of today (08/14/18) with:

PATCH /domains/{domain_id}/config/{group}

I attached what I ran, I will poke into the protected() more as I couldn't get it to leak me anything right now.

Changed in keystone:
status: New → Confirmed
importance: Undecided → High
Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

Subscribing Adam as I have looped him in via IRC for a related conversation.

Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

As a note, the additional cases outlined do require authentication (the get_member_from driver, and callback) but still could leak inappropriate data to the API.

Revision history for this message
Lance Bragstad (lbragstad) wrote :

Is the proposed solution to add a try/except to handle NOT FOUND and raise FORBIDDEN instead?

Revision history for this message
Gage Hugo (gagehugo) wrote :

@Lance

That is what I would say to do for the backports, it looks like flask fixes it for us (in Stein)

Revision history for this message
Gage Hugo (gagehugo) wrote :

Here's a patch for removing those domain existence checks.

Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

This should be fixed for master in moving to Flask.

Revision history for this message
Jeremy Stanley (fungi) wrote :

In keeping with recent OpenStack vulnerability management policy changes, no report should remain under private embargo for more than 90 days. Because this report predates the change in policy, the deadline for public disclosure is being set to 90 days from today. If the report is not resolved within the next 90 days, it will revert to our public workflow as of 2020-05-27. Please see http://lists.openstack.org/pipermail/openstack-discuss/2020-February/012721.html for further details.

description: updated
Revision history for this message
Colleen Murphy (krinkle) wrote :

For the same reasons that we closed https://bugs.launchpad.net/keystone/+bug/1840288 I would propose that we make this issue public and consider closing it as "won't fix".

Revision history for this message
Jeremy Stanley (fungi) wrote :

I'm in favor of switching this to public sooner rather than later. Whether Keystone maintainers consider this a bug will to some extent influence whether the VMT considers an advisory warranted, but I agree it doesn't sound critical, just a (possibly surprising?) behavior which should be documented clearly if it's not already.

Revision history for this message
Gage Hugo (gagehugo) wrote :

Agreed with Colleen here in comment #14, we can close it as "won't fix" due to the same reasons as the bug linked, plus the fact that this does not appear to be an issue with the migration to Flask in Stein.

Revision history for this message
Jeremy Stanley (fungi) wrote :

As there seems to be some consensus, I've gone ahead and switched this bug to public, marking our security advisory task Won't Fix. I'll leave it to the Keystone maintainers to do the same with theirs.

description: updated
information type: Private Security → Public
Changed in ossa:
status: Incomplete → Won't Fix
tags: added: security
Changed in keystone:
status: Confirmed → Won't Fix
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.