[OSSA 2013-022] Possibly DoS attack using object tombstones (CVE-2013-4155)
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
OpenStack Object Storage (swift) |
Fix Released
|
Critical
|
Peter Portante | ||
Folsom |
Fix Committed
|
Undecided
|
Unassigned | ||
Grizzly |
Fix Committed
|
Undecided
|
Unassigned | ||
OpenStack Security Advisory |
Fix Released
|
Medium
|
Thierry Carrez |
Bug Description
Is it possible for an attacker can fill a disk with old tombstones, slowing down object servers in the least with DELETE requests? I am not entirely sure I understand all of the DELETE behavior.
See the following patch which is a unit test which details the behavior (this currently fails on the last check because no metadata is pulled from the tombstone, so the container update is always performed).
diff --git a/test/
index e3f24d6..27f75d9 100755
--- a/test/
+++ b/test/
@@ -1410,6 +1410,115 @@ class TestObjectContr
+ def test_DELETE_
+ # Test swift.object_
+ # updates, making sure container update is called in the correct
+ # state.
+ timestamp = normalize_
+ req = Request.
+ headers={
+ 'X-Timestamp': timestamp,
+ 'Content-Type': 'application/
+ 'Content-Length': '4',
+ })
+ req.body = 'test'
+ resp = self.object_
+ self.assertEqua
+
+ calls_made = [0]
+
+ def our_container_
+ calls_made[0] += 1
+
+ orig_cu = self.object_
+ self.object_
+ try:
+ # The following request should return 204, but the object won't be
+ # truly deleted (container update is not performed) because the
+ # timestamp is old. A tombstone file should have been created with
+ # this timestamp.
+ #
+ # FIXME - When we know a newer file exists, should this not return
+ # HTTPConflict, and a tombstone not be created?
+ timestamp = normalize_
+ req = Request.
+ environ=
+ headers=
+ resp = self.object_
+ self.assertEqua
+ objfile = os.path.
+ storage_
+ hash_path('a', 'c', 'o')),
+ timestamp + '.ts')
+ self.assert_
+ self.assertEqua
+
+ # The following request should return 204, and the object should
+ # be truly deleted (container update is performed) because this
+ # timestamp is newer. A tombstone file should have been created
+ # with this timestamp.
+ sleep(.00001)
+ timestamp = normalize_
+ req = Request.
+ environ=
+ headers=
+ resp = self.object_
+ self.assertEqua
+ objfile = os.path.
+ storage_
+ hash_path('a', 'c', 'o')),
+ timestamp + '.ts')
+ self.assert_
+ self.assertEqua
+
+ # The following request should return a 404, as the object should
+ # already have been deleted, but it should have also performed a
+ # container update because the timestamp is newer, and a tombstone
+ # file should also exist for this timestamp.
+ #
+ # FIXME - A malicious client can cause a set of object servers to
+ # update containers and fill the volume with .ts files as the code
+ # stands: if the file is already deleted, should this not just
+ # return a 404 and avoid all the updates and tombstones?
+ sleep(.00001)
+ timestamp = normalize_
+ req = Request.
+ environ=
+ headers=
+ resp = self.object_
+ self.assertEqua
+ objfile = os.path.
+ storage_
+ hash_path('a', 'c', 'o')),
+ timestamp + '.ts')
+ self.assert_
+ self.assertEqua
+
+
+ # The following request should return a 404, as the object should
+ # already have been deleted, and it should not have performed a
+ # container update because the timestamp is oler, though a
+ # tombstone file should also have been created with this
+ # timestamp.
+ #
+ # FIXME - A malicious client can cause an object server to fill up
+ # the volume with .ts files as the code stands: should we not
+ # allow new tombstone files to be create without older timestamps?
+ timestamp = normalize_
+ req = Request.
+ environ=
+ headers=
+ resp = self.object_
+ self.assertEqua
+ objfile = os.path.
+ storage_
+ hash_path('a', 'c', 'o')),
+ timestamp + '.ts')
+ self.assert_
+ self.assertEqua
+ finally:
+ self.object_
+
def test_call(self):
""" Test swift.object_
inbuf = StringIO()
CVE References
Changed in ossa: | |
status: | New → Incomplete |
Changed in swift: | |
status: | New → Confirmed |
information type: | Private Security → Public Security |
Changed in swift: | |
status: | In Progress → Fix Committed |
Changed in swift: | |
status: | Fix Committed → Fix Released |
Here is a stab at a patch. I can run this through gerrit if appropriate.