Comment 31 for bug 1449212

Revision history for this message
Samuel Merritt (torgomatic) wrote :

You need more than one tempurl to actually retrieve objects. Maybe this?

Description:
Richard Hawkins from Rackspace reported a vulnerability in Swift container-scoped tempurls. When in possession of a tempurl key for a Swift container, a malicious actor may retrieve objects within any other container for the same Swift account (tenant) environment.

------

There are two related ways to exploit this:

The first way: given a tempurl for an object generated using a key on that object's container, one can PUT a manifest (i.e. object with X-Object-Manifest) to that URL, then HEAD the new object and, by observing the Etag and Content-Length contained within the HEAD response, learn whether an object starting with the given prefix exists.

For example, given two containers "red" and "blue" and a PUT tempurl for /v1/a/red/manifest, one can PUT /v1/a/red/manifest with header "X-Object-Manifest: /blue/abcd". A subsequent HEAD request for /v1/a/red/manifest will receive a response with an Etag and a Content-Length; the Etag is the MD5 hash of the Etags of all objects matching /v1/a/blue/abcd*, and the Content-Length is the sum of their lengths. If the Etag is "d41d8cd98f00b204e9800998ecf8427e" (the MD5 of the empty string), then there are no objects whose names match /v1/a/blue/abcd*. One can then overwrite the manifest with another that has a different X-Object-Manifest value, and in this way, can learn the names, lengths, and Etags of every object in container "blue".

The second way: given a tempurl *key* for a container, you can construct a PUT tempurl and a GET tempurl for the same object. Then, using the same procedure as above, discover the name of an object in the "blue" container. Then, PUT a manifest with "X-Object-Manifest: /blue/other-object-name", and finally, use the GET tempurl to download /v1/a/blue/other-object-name.

Both these exploits rely on large-object GET requests being able to examine segments outside the manifest's container even though the request was signed with a container-level tempurl key.