Tenants can be created with invalid ids

Bug #1379077 reported by Bryan D. Payne
8
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Identity (keystone)
Won't Fix
Medium
Dolph Mathews
Icehouse
Won't Fix
Medium
Unassigned
Juno
Won't Fix
Medium
Unassigned
OpenStack Security Advisory
Won't Fix
Medium
Unassigned

Bug Description

When creating a new tenant, there is an optional argument 'id' that may be passed:

https://github.com/openstack/keystone/blob/9025b64a8f2bf5cf01a18453d6728e081bd2c3b9/keystone/assignment/controllers.py#L114

If not passed, this just creates a uuid and proceeds. If a value is passed, it will use that value. So a user with priv's to create a tenant can pass something like "../../../../../" as the id. If this is done, then the project can't be deleted without manually removing the value from the database. This can lead to a DoS that could fill the db and take down the cloud, in the worst of circumstances.

I believe the proper fix here would be to just remove this feature altogether. But this is because I'm not clear about why we would ever want to allow someone to set the id manually. If there's a valid use case here, then we should at least do some input validation.

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

Looks like that line of code hasn't been touched since before Icehouse.

Changed in ossa:
status: New → Incomplete
tags: added: icehouse-backport-potential juno-backport-potential
Revision history for this message
Jeremy Stanley (fungi) wrote :

Keystone devs: are you to the point with RBAC that it's expected admins might grant tenant creation rights to non-administrators? If so, this is likely something we need to embargo until fixed.

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

Hi Brian and Jeremy,

If we removed the functionality I'm not sure if we'd break existing deployments who use that feature but it's a possibility. Some sort of validation could be added and ported to previous releases. We do have input validation with jsonschema in v3, but I don't think we allow the user to specify the project['id'] in v3 (region['id']s can be specified however).

What about using something like shlex?

Revision history for this message
Bryan D. Payne (bdpayne) wrote :

shlex feels more expressive than we need here. Perhaps we should start by coming to common ground on this question: What are the valid inputs for this field? Is it just uuid style strings? Or would other things be valid too?

If we could limit it to uuid4 input, then the following could work:

try:
    valid_id = UUID(tenant_ref['id'], version=4)
except ValueError, KeyError:
    valid_id = uuid.uuid4().hex

Revision history for this message
Dolph Mathews (dolph) wrote :

While this isn't a documented feature in terms of examples, there is room in the v2 API spec to see this as a feature (the spec is not well defined). That said, the behavior has actually been around since Essex (so: forever):

  https://github.com/openstack/keystone/blob/308a766b5b8ddbfbaa549e3af7fa736c1e1d4218/keystone/identity/core.py#L120-L122

Given that it's been around for so long, someone is surely using it (and with input beyond just uuid-looking things, otherwise, why would you use it?), so I agree that dropping support is probably the wrong solution. Simplest solution would be to validate it against a configurable regex, similar to what we do for v3 in Juno (where we have a handful of intentionally user-definable IDs, such as region IDs), i.e. ([a-zA-z0-9-]){1,64}

Jeremy Stanley (fungi)
Changed in ossa:
status: Incomplete → Confirmed
importance: Undecided → Medium
description: updated
Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

I completely agree we cannot remove the feature. The solution proposed by Dolph is really quick to get rolled up into a patch set and makes sense to use as the fix as it is consistent with the other cases we allow user defined ids

Dolph Mathews (dolph)
Changed in keystone:
assignee: nobody → Dolph Mathews (dolph)
importance: Undecided → Medium
status: New → Confirmed
Revision history for this message
Lance Bragstad (lbragstad) wrote :

Started working on a patch for this. Dolph, do you want the diff?

Revision history for this message
Bryan D. Payne (bdpayne) wrote :

A configurable regex sounds like a reasonable approach. I'd really like to be able to filter based on arbitrary python code (think flask converter), but if the framework isn't already in place for that, then it's certainly beyond scope for this fix.

Revision history for this message
Dolph Mathews (dolph) wrote :

Lance: let's catch up offline.

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

Bryan, we'll work with the regex path for now.

Revision history for this message
Bryan D. Payne (bdpayne) wrote :

Sounds good. Thanks for taking this on!

Revision history for this message
Dolph Mathews (dolph) wrote :

Sharing the solution discussed above based on regex, but we have LDAP tests that expect to pass unicode characters as the ID without encoding them. This patch is written to accommodate unicode (re.UNICODE is enabled), but I think those LDAP tests are wrong, so I'm now working on a second solution for comparison.

This patch applies to both master and proposed/juno.

Revision history for this message
Bryan D. Payne (bdpayne) wrote :

I agree that it would be best to exclude unicode. Otherwise, this looks ok to me from a security viewpoint. I'll leave it to keystone core to decide if the solution is generally correct for keystone.

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

Pulled this down and tested it manually and it works as expected. I also switched the regex to be more strict and that also works as expected. The help information for the configuration is nice and descriptive.

I'm good with this change.

+2

Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

Any chance we can get this fix backported to stable/icehouse and the upcoming stable/juno ?
Quid of the stable backports that introduce a new configuration option with a sane default...

In the meantime, here is an impact description draft #1:

Title: Keystone allows creation of tenant with invalid ids
Reporter: Bryan D. Payne (Nebula)
Products: Keystone
Versions: up to 2014.2.1

Description:
Bryan D. Payne from Nebula reported a vulnerability in Keystone tenant creation. By creating malicious tenants with invalid id like "../../../../../" an authenticated user may corrupt keystone database resulting in new tenant being not removable, potentially leading to denial of service trough resources exhaustion. Note that by default only administrator have tenant creation permission, and the faulty tenants can still be deleted manually from the database. All Keystone setups are affected.

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

The code looks good to me in #12 (+2).

For the description I would suggest that we change "By creating malicious tenants with invalid id like "../../../../../" an authenticated user may corrupt keystone database resulting in new tenant being not removable, potentially leading to denial of service trough resources exhaustion."

to

"An authenticated user is able to create tenants with invalid ids like '../../../../../' that cannot be removed via the REST API potentially leading to a denial of service through resource exhaustion."

This isn't really a corruption of the DB, no data is lost directly via this issue (indirectly, MySQL could have serious issues, but that could occur with other cases of too much data on disk as well).

Changed in keystone:
status: Confirmed → In Progress
Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

Thanks Morgan!

removing the corruption bit, here is an updated impact description #2

Title: Keystone allows creation of tenant with invalid ids
Reporter: Bryan D. Payne (Nebula)
Products: Keystone
Versions: up to 2014.2.1

Description:
Bryan D. Payne from Nebula reported a vulnerability in Keystone tenant creation. By creating malicious tenants with invalid id like "../../../../../" an authenticated user may fill the keystone database with tenants that cannot be removed via the REST API potentially leading to a denial of service through resource exhaustion. Note that by default only administrator have tenant creation permission, and the faulty tenants can still be deleted manually from the database. All Keystone setups are affected.

Revision history for this message
Dolph Mathews (dolph) wrote :

+1 for impact description in #17

Revision history for this message
Dolph Mathews (dolph) wrote :

This is my preferred solution. Instead of configurable regex, it uses urllib to verify that the input tenant ID is url-safe. There is no configuration impact.

It also changes two LDAP tests which were creating tenants with Unicode IDs to use pure ASCII (otherwise those tests would fail against this new validation).

This patch applies to master and proposed/juno.

Revision history for this message
Bryan D. Payne (bdpayne) wrote :

+1 for impact description in #17

Revision history for this message
Dolph Mathews (dolph) wrote :

Small revision to the patch that I had just posted in #19. This just re-uses an i18n error message. The rest of comment #19 still applies here.

Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

@Dolph that surely sounds more simple and thus easy to backport!

 I can't find the patch, did you forget to attach it ?

Revision history for this message
Bryan D. Payne (bdpayne) wrote :

Dolph, I'm not seeing a link to your urllib based patch.

Revision history for this message
Dolph Mathews (dolph) wrote :

Tristan: Bryan: My apologies, I was hoping to post a quick revision before anyone noticed :) See comment #21.

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

+1 for the description provided in comment #17.

Revision history for this message
Tristan Cacqueray (tristan-cacqueray) wrote :

Oups, a tight comment race happened :-)

So, the patch seems to apply on stable/icehouse, but tests might need some rework to apply cleanly.

Revision history for this message
Dolph Mathews (dolph) wrote :

stable/icehouse backport of the urllib solution is attached.

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

I have confirmed the patch in #21 works as expected. The code looks good.

The description in #17 looks good except a small typo: "Note that by default only administrator have tenant creation permission" should either be: "Note that by default only administrators have tenant creation permission" (administrator should be plural).

I am ok with it as is without the typo change.

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

I am still reviewing the code in #28. At a glance it looks good.

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

The patch set from #27 works for me on stable/icehouse.

+2

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

The patch from #27 looks good to me.

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

Before we move forward with getting a CVE assigned for this issue I'd like to revisit whether it really needs to be handled as a security flaw. I'm not sure where the trust boundary is being crossed here. The user must already be given access rights to create a tenant so aside from not being easily deleted how is this abuse case different from creating a bunch tenants with valid ID's?

I think Jeremy originally touched on this in comment #2 and I'm not sure that question was ever answered?

Revision history for this message
Bryan D. Payne (bdpayne) wrote :

This is a DoS and a consistency issue. The scope and impact are going to depend on how a given cloud is configured. But, from an operational context, it is typically harder to find someone that can manually manipulate the backend db than it is to find someone that can drive the OpenStack CLI tools. And I think that gives this particular issue a higher impact.

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

From an attacker perspective, triggering a DoS by creating millions of tenants is the same attack, whether this bug is fixed or not. That's what I cause "normal usage" DoS -- there is no amplification here that would suddenly make it more viable than normal usage, and the "DoS" is undistinguishable from a peak of activity. The fact that you can't delete the newly-created tenants using admin CLI is a bug, it doesn't make "DoS by creating a bunch of tenants" more (or less) efficient.

So I don't think this qualifies as a vulnerability.

Revision history for this message
Dolph Mathews (dolph) wrote :

From a security standpoint, I don't see this as being a significant risk.

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

I agree with Dolph. This is low risk. I do think it'll provide significant annoyance, but likely not much else, to a deployer to cleanup after in the worst case (as outlined by Thierry).

Revision history for this message
Bryan D. Payne (bdpayne) wrote :

I'm ok making this public. My primary concern at this point is seeing this bug fixed. I agree that this is borderline based on the definition of vulnerability typically used by the VMT.

Jeremy Stanley (fungi)
information type: Private Security → Public
tags: added: security
Changed in ossa:
status: Confirmed → Won't Fix
tags: removed: icehouse-backport-potential
Alan Pevec (apevec)
tags: removed: juno-backport-potential
Revision history for this message
Morgan Fainberg (mdrnstm) wrote :

With V2 slowly disappearing, i am marking this as Wont Fix.

Changed in keystone:
status: In Progress → 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.