[OSSA-2014-041] Glance allows users to download and delete any file in glance-api server (CVE-2014-9493)
| Affects | Status | Importance | Assigned to | Milestone | ||
|---|---|---|---|---|---|---|
| | Glance |
Critical
|
Grant Murphy | |||
| | Icehouse |
Critical
|
Zhi Yan Liu | |||
| | Juno |
Critical
|
Zhi Yan Liu | |||
| Juniper Openstack | Status tracked in Trunk | |||||
| | Trunk |
Critical
|
Unassigned | |||
| | OpenStack Security Advisory |
Critical
|
Grant Murphy | |||
| | openstack-ansible |
Critical
|
Ian Cordasco | |||
| | Icehouse |
Critical
|
Ian Cordasco | |||
| | Juno |
Critical
|
Ian Cordasco | |||
Bug Description
Updating image-location by update images API users can download any file for which glance-api has read permission.
And the file for which glance-api has write permission will be deleted when users delete the image.
For example:
When users specify '/etc/passwd' as locations value of an image user can get the file by image download.
When locations of an image is set with 'file:/
How to recreate the bug:
download files:
- set show_multiple_
- create a new image
- set locations of the image's property a path you want to get such as file:///etc/passwd.
- download the image
delete files:
- set show_multiple_
- create a new image
- set locations of the image's property a path you want to delete such as file://
- delete the image
I found this bug in 2014.2 (742c898956d655
What a big A RE RE!!
CVE References
| summary: |
- Glance allows users to download any file in glance-api server + Glance allows users to download and delete any file in glance-api server |
| description: | updated |
| Changed in ossa: | |
| status: | New → Incomplete |
| Grant Murphy (gmurphy) wrote : Re: Glance allows users to download and delete any file in glance-api server | #1 |
| Stuart McLaren (stuart-mclaren) wrote : | #2 |
I checked out 742c898956d655a
I checked the server startup log to be sure it was set:
2014-12-10 16:37:23.803 6847 DEBUG glance.
With the default store set to either file or swift I got:
$ glance image-update 7450abb5-
<html>
<head>
<title>400 Bad Request</title>
</head>
<body>
<h1>400 Bad Request</h1>
External sourcing not supported for store 'file'<br /><br />
</body>
</html> (HTTP 400)
Can you provide more info (eg config files) to help reproduce?
Thanks.
| Stuart McLaren (stuart-mclaren) wrote : | #3 |
Reproduced:
$ glance --os-image-
+------
| Property | Value |
+------
| checksum | 398759a311bf25c
| container_format | bare |
| created_at | 2014-12-
| disk_format | raw |
| file | /v2/images/
| id | 7450abb5-
| locations | [{"url": "file:/
| | "metadata": {}}, {"url": "file:/
| min_disk | 0 |
| min_ram | 0 |
| name | img1 |
| owner | f68be3a5c2b1472
| protected | False |
| schema | /v2/schemas/image |
| size | 106 |
| status | active |
| tags | [] |
| updated_at | 2014-12-
| visibility | private |
+------
$ glance image-download 7450abb5-
LABEL=cloudimg-
/dev/vdb /mnt auto defaults,
(py27)ubuntu in ~/git/python-
| Changed in glance: | |
| status: | New → Confirmed |
| Stuart McLaren (stuart-mclaren) wrote : | #4 |
Note: v2 only I think.
| Stuart McLaren (stuart-mclaren) wrote : | #5 |
Note: set_image_location policy defaults to "" -- ie allowed by anyone. We should consider changing that to admin only.
| Changed in glance: | |
| importance: | Undecided → High |
| Stuart McLaren (stuart-mclaren) wrote : | #6 |
This can be exploited even when the server is configured with "show_multiple_
(This is more serious because that is the default setting. )
2014-12-10 17:35:45.137 10953 DEBUG glance.
Just patch the client (or send the equivalent request directly with curl):
$ git diff
diff --git a/glanceclient/
index 6ec9250..5037553 100644
--- a/glanceclient/
+++ b/glanceclient/
@@ -217,12 +217,10 @@ class Controller(object):
:param metadata: Metadata associated with the location.
:returns: The updated image
"""
- image = self._get_
- url_list = [l['url'] for l in image.locations]
- if url in url_list:
- err_str = 'A location entry at %s already exists' % url
- raise exc.HTTPConflic
-
+ #image = self._get_
+ #url_list = [l['url'] for l in image.locations]
+ #if url in url_list:
+ # err_str = 'A location entry at %s already exists' % url
add_patch = [{'op': 'add', 'path': '/locations/-',
$ glance image-create --disk-format raw --container-format bare
+------
| Property | Value |
+------
| checksum | None |
| container_format | bare |
| created_at | 2014-12-10T17:36:13 |
| deleted | False |
| deleted_at | None |
| disk_format | raw |
| id | ca95d79e-
| is_public | False |
| min_disk | 0 |
| min_ram | 0 |
| name | None |
| owner | f68be3a5c2b1472
| protected | False |
| size | 0 |
| status | queued |
| updated_at | 2014-12-10T17:36:13 |
| virtual_size | None |
+------
$ glance --os-image-
+------
| Property | Value |
+------
| container_format | bare ...
| Changed in ossa: | |
| status: | Incomplete → Confirmed |
| importance: | Undecided → High |
I haven't taken a closer look at this but my guess is that this behavior is down to filesystem store. Glance creates filesystem store for the location 'file:///' and fetches/deletes the images using this store. However, the fielsystem store isn't enforcing whether or not a given image location falls within the path where the images are usually stored. This path is indicated by 'filesystem_
https:/
https:/
For a quick fix, we can add a check to ensure that image location MUST fall under the path indicated by 'filesystem_
This assessment maybe completely off, please do correct me in that case. I shall take a closer look at this soon-ish.
| Masahito Muroi (muroi-masahito) wrote : | #8 |
I use v2 like Stuart mentioned in #4.
I realized that user also can get http responses from openstack or no openstack systems in DC. If operators have web based utility tools which don't authorize requests in the DC user can download the info. OpenStack API which require a token with requests don't matter this since glance checks first reachabilities for the location in the location-add.
| Changed in glance: | |
| assignee: | nobody → Zhi Yan Liu (lzy-dev) |
| Zhi Yan Liu (lzy-dev) wrote : | #9 |
Hi Stuart, Hemanth,
Thanks for your analysis.
As an alternative solution regarding to changing store drive that Hemanth proposed above, I think we could make a similar limitation/check on image location update api like what we did in v1 [0] as well, to prevent user use patch api to handle file and swift location? A unique benefit of the way is that, IMO, it could make v2 api be consistent with v1 on this kind of request from client's perspective.
[0] https:/
Thoughts?
| Flavio Percoco (flaper87) wrote : | #10 |
I agree with Zhi that a good, quick and probably most importantly *backportable* solution would be to add a similar check in v2 as we have in v1.
A future follow-up patch should a a proper verification process in the store code and make the server side use it.
| Stuart McLaren (stuart-mclaren) wrote : | #11 |
Yes, I was also thinking adding the v1 style limitation to v2 is probably a good idea.
I'd also like to see the set and get location policies default to admin only -- what do others think about that? (IMHO playing directly with the locations should be something that power users 'opt in' to be able to do.)
| Zhi Yan Liu (lzy-dev) wrote : | #12 |
Hi Stuart, I'm thinking if that way/rule could be overkill for the image owner? For example, probably end user prepared/had an image content from an existing storage, then, IMO it's sensible to allow end user adds that location to own image. Am I miss any ting?
| Stuart McLaren (stuart-mclaren) wrote : | #13 |
> IMO it's sensible to allow end user adds that location to own image.
It is currently an operator decision. Some operators will want to allow this and others will not. The question is: which is a better default for the set_image_location policy? My feeling is that a lot of new operators may not necessarily understand the finer details of allowing a user to set image locations directly. When it is enabled, there are far fewer assumptions that an operator can make about the state of the glance system, and the image data paths, which complicates administration.
It also increases the attack surface a lot (eg this and other bugs). I personally would like turning on the ability to set locations be an explicit decision by the operator -- that gives them a chance to consciously weigh up the advantages and disadvantages, and to 'nudge' them to leave it disabled unless they really need it.
| Thierry Carrez (ttx) wrote : | #14 |
Changing the set/get location policies default to admin only is not a bad idea, but that's a different patch (master only).
For the (backportable) vulnerability fix, we ideally need something which would close the hole without chaging behavior for "normal" users. Are there valid use cases for specifying a file:// location ? If not, I think having a v1-style check in v2 is the simplest solution.
| Zhi Yan Liu (lzy-dev) wrote : | #15 |
For the direction/idea of fixing driver, like Hemanth mentioned above, something in my mind is that: Totally I think it's a worth thing to get due to I think we'd better don't suppose glance_store lib are used by glance only, other project, e.g. Nova, probably could leverage it as well. I'm a little worried if that way could be a blocker for migration or upgrade operation on glance however, if we always checks if given image location are lived in configured storage directory(s) at [0], we could prevent the problem happen, but if operator changed option of glance-api with a new storage folder and want to keep existing image works (the existing locations in db are pointing to original path), this approach will cause all location of existing images to be invalid, and limits operator to do that kind of migration/upgrade operation - he/she can't change storage directory(s) option even there's an available image, unless updating db at the same time, but I think it's a little heavy.
Any thoughts?
Thanks
Btw, the fix for glance was proposed at https:/
Now that the cat is unfortunately out of the bag, I switch this bug to public security.
| Changed in glance: | |
| importance: | High → Critical |
| Changed in ossa: | |
| importance: | High → Critical |
| information type: | Private Security → Public Security |
| Thierry Carrez (ttx) wrote : | #17 |
Since this was unfortunately disclosed too early, posting a mitigation solution would be good. My understaning is that setting the set_image_location policy to admin-only is a way to work around the issue temporarily. Glance core, could you confirm ?
| Zhi Yan Liu (lzy-dev) wrote : | #18 |
Thierry, I'm sorry for that! I consider it's a valid workaround way, to switch set_image_location policy to admin.
| Grant Murphy (gmurphy) wrote : | #19 |
Draft impact description -
Title: Glance v2 API unrestricted path traversal
Reporter: Masahito Muroi (NTT)
Products: Glance
Versions: Versions 2012.2 up to 2014.2.1
Description:
Masahito Muroi from NTT reported a vulnerability in Glance v2 API. By setting a malicious image location an authenticated user can download or delete any file on the Glance server for which the glance-api process user has access to. Only setups using the Glance v2 API are affected by this flaw.
Note:
A potential mitigation strategy available for operators is to change the glance policy to restrict access to administrators for get_image_location, set_image_location, and delete_
| Nikhil Komawar (nikhil-komawar) wrote : | #20 |
The setting of policy to admin only makes sense.
However, there is a risk of backward incompatibility if a existing deployment runs with this assumption (and they knowingly change the policy in adherence to the security issue). Given the nature of the risk it (admin only policy) seems like a decent trade-off until a cleaner solution is proposed. We'd try to get the better fix sooner in kilo.
Thanks!
| Changed in glance: | |
| milestone: | none → kilo-1 |
| status: | Confirmed → In Progress |
@Grant, the affected version may be too broad, the bug might have been introduced by https:/
Versions: up to 2014.1.3 and 2014.2 version up to 2014.2.1
Also while the leak seems to happens on the glance-api server, shouldn't we also consider registry and storage node to be likely affected as well ?
| Zhi Yan Liu (lzy-dev) wrote : | #22 |
| Abel Lopez (al592b) wrote : | #23 |
Is this limited to default_store=file ?
I'm unable to replicate using default_store=rbd
| Matteo Panella (mpanella) wrote : | #24 |
I can confirm that the issue can be reproduced on a fully up-to-date Icehouse installation with the default configuration (both v1 and v2 API enabled). The only prerequisites to reproduce it are a recent version of python-glanceclient (newer than 0.14.0 due to lp:1367326) and the patch mentioned in #6.
As a sidenote, after patching glance (or the policy) all credentials stored in files accessible by glance (especially those related to the operation of glance itself) should be revoked as a precautionary measure.
Can someone please propose a backport to Icehouse and Juno of the change https:/
At least tests could not be trivially cherry-picked...
| Erno Kuvaja (jokke) wrote : | #26 |
Tristan: I'm on it.
| Flavio Percoco (flaper87) wrote : | #27 |
@Erno I've done Juno already and Zhi Yan is doing Icehouse.
Fix proposed to branch: stable/juno
Review: https:/
| Zhi Yan Liu (lzy-dev) wrote : Re: Glance allows users to download and delete any file in glance-api server | #29 |
Icehouse: https:/
Change abandoned by Erno Kuvaja (<email address hidden>) on branch: stable/juno
Review: https:/
Reason: dup
| tags: | added: havana-backport-potential |
| Changed in glance: | |
| status: | In Progress → Fix Committed |
| Changed in glance: | |
| status: | Fix Committed → Fix Released |
| Nikhil Komawar (nikhil-komawar) wrote : Re: Glance allows users to download and delete any file in glance-api server | #31 |
Havana is not supported now. Removing the tag after discussing the same with Tristan Cacqueray.
| tags: | removed: havana-backport-potential |
| Changed in ossa: | |
| status: | Confirmed → In Progress |
| Thierry Carrez (ttx) wrote : | #32 |
OSSA out, waiting for CVE allocation
| Changed in ossa: | |
| status: | In Progress → Fix Committed |
| summary: |
- Glance allows users to download and delete any file in glance-api server + [OSSA-2014-041] Glance allows users to download and delete any file in + glance-api server (CVE-2014-9493) |
| George Shuklin (george-shuklin) wrote : | #33 |
About Havana:
I think havana is not affected:
Here Icehouse fix: https:/
And this is havana code:
def _validate_
if source:
for scheme in ['s3', 'swift', 'http', 'rbd', 'sheepdog', 'cinder']:
if source.
msg = _("External sourcing not supported for store %s") % source
raise HTTPBadRequest(
Basically, havana will not accept anything except listed ('s3', 'swift', 'http', 'rbd', 'sheepdog', 'cinder'), and will rejects schemes 'file' and 'swift+config'.
| Zhi Yan Liu (lzy-dev) wrote : | #34 |
The key point for this issue is about the location validation missing in image v2 patch api, v1 stuff is ok for all havana, icehouse, juno releases.
Base on code, technically I'm sure stable/havana has this defect as well. ref https:/
| Changed in openstack-ansible: | |
| importance: | Undecided → Critical |
| assignee: | nobody → Ian Cordasco (icordasc) |
Fix proposed to branch: master
Review: https:/
| Changed in openstack-ansible: | |
| status: | New → In Progress |
Reviewed: https:/
Committed: https:/
Submitter: Jenkins
Branch: master
commit 233a71022e0ee90
Author: Ian Cordasco <email address hidden>
Date: Wed Jan 7 10:38:50 2015 -0600
Prevent user from accessing privileged files
Closes-bug: 1400966
Related to OSSA-2014-041
CVE-2014-9493
Change-Id: I869b88cfe1bb82
| Changed in openstack-ansible: | |
| status: | In Progress → Fix Committed |
| Changed in ossa: | |
| status: | Fix Committed → Fix Released |
| Jin Liu (jin-t) wrote : | #37 |
I merged this fix of icehouse then found one issue, I can still download file when use filesystem://, while I cannot delete file. When use file:// it looks working fine.
[<email address hidden>] /etc # glance image-create --disk-format raw --container-format bare
+------
| Property | Value |
+------
| checksum | None |
| container_format | bare |
| created_at | 2015-01-07T00:28:17 |
| deleted | False |
| deleted_at | None |
| disk_format | raw |
| id | c0294cd0-
| is_public | False |
| min_disk | 0 |
| min_ram | 0 |
| name | None |
| owner | f28900596cdd400
| protected | False |
| size | 0 |
| status | queued |
| updated_at | 2015-01-07T00:28:17 |
| virtual_size | None |
+------
[<email address hidden>] /etc #
[<email address hidden>] /etc # glance image-update --location filesystem:
+------
| Property | Value |
+------
| checksum | None |
| container_format | bare |
| created_at | 2015-01-07T00:28:17 |
| deleted | False |
| deleted_at | None |
| disk_format | raw |
| id | c0294cd0-
| is_public | False |
| min_disk | 0 |
| min_ram | 0 |
| name | None |
| owner | f28900596cdd400
| protected | False |
| size | 2292 |
| status | active |
| updated_at | 2015-01-07T00:28:32 |
| virtual_size | None |
+------
[<email address hidden>] /etc # glance image-list
+------
| ID | Name | Disk Format | Container Format | Size | Status |
+---------------...
| Changed in openstack-ansible: | |
| milestone: | none → 9.0.6 |
| milestone: | 9.0.6 → 10.1.2 |
| Changed in openstack-ansible: | |
| milestone: | 10.1.2 → 9.0.6 |
| milestone: | 9.0.6 → none |
| OpenStack Infra (hudson-openstack) wrote : Fix proposed to os-ansible-deployment (stable/icehouse) | #38 |
Fix proposed to branch: stable/icehouse
Review: https:/
Fix proposed to branch: stable/juno
Review: https:/
| OpenStack Infra (hudson-openstack) wrote : Change abandoned on os-ansible-deployment (stable/icehouse) | #40 |
Change abandoned by Ian Cordasco (<email address hidden>) on branch: stable/icehouse
Review: https:/
Reason: Sent to stable/icehouse instead of icehouse
| OpenStack Infra (hudson-openstack) wrote : Change abandoned on os-ansible-deployment (stable/juno) | #41 |
Change abandoned by Ian Cordasco (<email address hidden>) on branch: stable/juno
Review: https:/
Reason: Sent to stable/juno instead of juno
Fix proposed to branch: juno
Review: https:/
Fix proposed to branch: icehouse
Review: https:/
| no longer affects: | openstack-ansible/next |
| Grant Murphy (gmurphy) wrote : | #44 |
Looks as though the fix is incomplete. Using the filesystem URI scheme will still hit the same code path.
Juno and master are also affected.
| Grant Murphy (gmurphy) wrote : | #46 |
Reopening bug as fix was incomplete. Will request a new CVE id when a fix is ready.
| Changed in glance: | |
| status: | Fix Released → In Progress |
| assignee: | Zhi Yan Liu (lzy-dev) → Grant Murphy (gmurphy) |
| Changed in ossa: | |
| assignee: | nobody → Grant Murphy (gmurphy) |
| status: | Fix Released → In Progress |
Fix proposed to branch: master
Review: https:/
| Zhi Yan Liu (lzy-dev) wrote : | #48 |
I missed to block 'filesystem' due to file store support two schemas 'file' and 'filesystem', so the original solution is still correct, it just need to add 'filesystem' to disallowance list. Thanks Grant to add it.
| Zhi Yan Liu (lzy-dev) wrote : | #49 |
Minor improvement in async task for the reason https:/
Reviewed: https:/
Committed: https:/
Submitter: Jenkins
Branch: juno
commit b726fca969e88a4
Author: Ian Cordasco <email address hidden>
Date: Wed Jan 7 10:38:50 2015 -0600
Prevent user from accessing privileged files
Closes-bug: 1400966
Related to OSSA-2014-041
CVE-2014-9493
Change-Id: I869b88cfe1bb82
(cherry picked from commit 233a71022e0ee90
Reviewed: https:/
Committed: https:/
Submitter: Jenkins
Branch: icehouse
commit 0e42c95ff016dfc
Author: Ian Cordasco <email address hidden>
Date: Wed Jan 7 10:38:50 2015 -0600
Prevent user from accessing privileged files
Closes-bug: 1400966
Related to OSSA-2014-041
CVE-2014-9493
Change-Id: I869b88cfe1bb82
(cherry picked from commit 233a71022e0ee90
| Thierry Carrez (ttx) wrote : | #52 |
Let's track the filesystem: case on bug 1408663, for clarity.
| Changed in ossa: | |
| status: | In Progress → Fix Released |
| Changed in glance: | |
| status: | In Progress → Fix Released |
Related fix proposed to branch: master
Review: https:/
Reviewed: https:/
Committed: https:/
Submitter: Jenkins
Branch: master
commit e451978576f394b
Author: Tristan Cacqueray <email address hidden>
Date: Thu Jan 15 21:18:39 2015 +0000
Adds OSSA-2014-041
Change-Id: Idf8fc5be42dd1e
Related-Bug: #1400966
| Changed in glance: | |
| milestone: | kilo-1 → 2015.1.0 |
| Changed in openstack-ansible: | |
| status: | Fix Committed → Fix Released |
| Kyrylo Romanenko (kromanenko) wrote : | #55 |
On verification
| Kyrylo Romanenko (kromanenko) wrote : | #56 |
I have treied with several sequences of actions.
First i set show_multiple_
in /etc/glance/
and restarted glance by: glance-control all restart
Flow 1
1) Created small image via Horizon GUI.
2) glance --os-image-
The administrator has disabled API access to image locations (HTTP 400)
OK
Flow 2
1) Created small image via GUI.
2) Added Metadata via Horizon url=file:
3) glance image-download --file ~/small.iso f44eb9f7-
4) Checked contents of file - OK.
Flow 3
1) glance image-create --disk-format raw --container-format bare
2) glance --os-image-
The administrator has disabled API access to image locations (HTTP 400)
OK
Flow 4
1) glance image-create --disk-format raw --container-format bare
2) glance image-update --location filesystem:
<html>
<head>
<title>400 Bad Request</title>
</head>
<body>
<h1>400 Bad Request</h1>
External source are not supported: 'filesystem:
</body>
Almost good, but CLI output could be like in Flow 1 and 3.
| Kyrylo Romanenko (kromanenko) wrote : | #57 |
Environement:
VERSION:
feature_groups:
- mirantis
production: "docker"
release: "6.1"
openstack_
api: "1.0"
build_number: "432"
build_id: "2015-05-
nailgun_sha: "076566b5df37f6
python-
astute_sha: "cb655a9a9ad268
fuel-library_sha: "1621cb350af744
fuel-ostf_sha: "9ce18007490817
fuelmain_sha: "0e970647a83d9a
Deployment in VirtualBox. Ubuntu 14.04.1, Neutron VLAN, Cinder and Glance on LVM
1 Controller+Cinder
1 Compute+Cinder
1 Cinder
| Kyrylo Romanenko (kromanenko) wrote : | #58 |
Oh, i`d better to post it to MOS launchpad.
Review in progress for https:/
Submitter: Ganesha HV (<email address hidden>)
| Ganesha HV (ganeshahv) wrote : | #60 |
invalid Bug ID mentioned in commit


Thanks for the report, the OSSA task is set to incomplete pending additional security review from glance-coresec.