Add a test verifying cache deduplication is not sensitive to SHA1 collision attack
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Feb 2017 15:27:07 +0000 (15:27 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 27 Feb 2017 15:27:07 +0000 (15:27 +0000)
https://bugs.webkit.org/show_bug.cgi?id=168774

Reviewed by Alex Christensen.

We use SHA1 for deduplicating disk cache resources. Since a real world SHA1 collision was demonstrated
recently (http://shattered.io/) we can add a test that shows it can't be used for cache poisoning.

There are two protections in the cache code that both individually stop this type of attack:

- When deduplicating the data is verified to be equal by a bytewise comparison.
- SHA1 computations include random salt unique to cache instance.

Commenting out both protections is needed to make this test fail.

* http/tests/cache/disk-cache/resources/make-sha1-collision.php: Added.

This script turns the nocolliding pdfs into colliding ones on the fly, in memory. This way we don't need
to land the colliding versions and risk blowing up the infrastructure.

* http/tests/cache/disk-cache/resources/shattered-nocollision-1.pdf: Added.
* http/tests/cache/disk-cache/resources/shattered-nocollision-2.pdf: Added.

> shasum shattered-nocollision-*
5439274cf677fe3b7c51264f88a5ecee97319ee9  shattered-nocollision-1.pdf
7fdd163dc21064b7f26e1199fc560ee6e0307498  shattered-nocollision-2.pdf

* http/tests/cache/disk-cache/shattered-deduplication-expected.html: Added.
* http/tests/cache/disk-cache/shattered-deduplication.html: Added.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@213064 268f45cc-cd09-0410-ab3c-d52691b4dbfc

LayoutTests/ChangeLog
LayoutTests/http/tests/cache/disk-cache/resources/make-sha1-collision.php [new file with mode: 0644]
LayoutTests/http/tests/cache/disk-cache/resources/shattered-nocollision-1.pdf [new file with mode: 0644]
LayoutTests/http/tests/cache/disk-cache/resources/shattered-nocollision-2.pdf [new file with mode: 0644]
LayoutTests/http/tests/cache/disk-cache/shattered-deduplication-expected.html [new file with mode: 0644]
LayoutTests/http/tests/cache/disk-cache/shattered-deduplication.html [new file with mode: 0644]

index 43413fe..f820dce 100644 (file)
@@ -1,3 +1,35 @@
+2017-02-27  Antti Koivisto  <antti@apple.com>
+
+        Add a test verifying cache deduplication is not sensitive to SHA1 collision attack
+        https://bugs.webkit.org/show_bug.cgi?id=168774
+
+        Reviewed by Alex Christensen.
+
+        We use SHA1 for deduplicating disk cache resources. Since a real world SHA1 collision was demonstrated
+        recently (http://shattered.io/) we can add a test that shows it can't be used for cache poisoning.
+
+        There are two protections in the cache code that both individually stop this type of attack:
+
+        - When deduplicating the data is verified to be equal by a bytewise comparison.
+        - SHA1 computations include random salt unique to cache instance.
+
+        Commenting out both protections is needed to make this test fail.
+
+        * http/tests/cache/disk-cache/resources/make-sha1-collision.php: Added.
+
+        This script turns the nocolliding pdfs into colliding ones on the fly, in memory. This way we don't need
+        to land the colliding versions and risk blowing up the infrastructure.
+
+        * http/tests/cache/disk-cache/resources/shattered-nocollision-1.pdf: Added.
+        * http/tests/cache/disk-cache/resources/shattered-nocollision-2.pdf: Added.
+
+        > shasum shattered-nocollision-*
+        5439274cf677fe3b7c51264f88a5ecee97319ee9  shattered-nocollision-1.pdf
+        7fdd163dc21064b7f26e1199fc560ee6e0307498  shattered-nocollision-2.pdf
+
+        * http/tests/cache/disk-cache/shattered-deduplication-expected.html: Added.
+        * http/tests/cache/disk-cache/shattered-deduplication.html: Added.
+
 2017-02-27  Carlos Garcia Campos  <cgarcia@igalia.com>
 
         [GTK] Downloads attributes tests are failing
diff --git a/LayoutTests/http/tests/cache/disk-cache/resources/make-sha1-collision.php b/LayoutTests/http/tests/cache/disk-cache/resources/make-sha1-collision.php
new file mode 100644 (file)
index 0000000..0d9976a
--- /dev/null
@@ -0,0 +1,9 @@
+<?
+$path = $_GET['path'];
+header('HTTP/1.1 200 OK');
+header("Cache-control: max-age=10000");
+header("Content-Type: application/pdf");
+$content = file_get_contents($path);
+$collidingContent = str_replace("SVN is the best!", "SHA-1 is dead!!!", $content);
+echo $collidingContent;
+?>
diff --git a/LayoutTests/http/tests/cache/disk-cache/resources/shattered-nocollision-1.pdf b/LayoutTests/http/tests/cache/disk-cache/resources/shattered-nocollision-1.pdf
new file mode 100644 (file)
index 0000000..7fe2520
Binary files /dev/null and b/LayoutTests/http/tests/cache/disk-cache/resources/shattered-nocollision-1.pdf differ
diff --git a/LayoutTests/http/tests/cache/disk-cache/resources/shattered-nocollision-2.pdf b/LayoutTests/http/tests/cache/disk-cache/resources/shattered-nocollision-2.pdf
new file mode 100644 (file)
index 0000000..03558c4
Binary files /dev/null and b/LayoutTests/http/tests/cache/disk-cache/resources/shattered-nocollision-2.pdf differ
diff --git a/LayoutTests/http/tests/cache/disk-cache/shattered-deduplication-expected.html b/LayoutTests/http/tests/cache/disk-cache/shattered-deduplication-expected.html
new file mode 100644 (file)
index 0000000..25959be
--- /dev/null
@@ -0,0 +1,4 @@
+<iframe src="resources/shattered-nocollision-1.pdf" width=100 height=100></iframe>
+<iframe src="resources/shattered-nocollision-2.pdf" width=100 height=100></iframe>
+<iframe src="resources/shattered-nocollision-1.pdf" width=100 height=100></iframe>
+<iframe src="resources/shattered-nocollision-2.pdf" width=100 height=100></iframe>
diff --git a/LayoutTests/http/tests/cache/disk-cache/shattered-deduplication.html b/LayoutTests/http/tests/cache/disk-cache/shattered-deduplication.html
new file mode 100644 (file)
index 0000000..b59655c
--- /dev/null
@@ -0,0 +1,37 @@
+<body>
+<script>
+if (window.testRunner)
+    testRunner.waitUntilDone();
+
+function makeCollision(file)
+{
+    return "resources/make-sha1-collision.php?path=" + file;
+}
+
+function addImageFrame(src, timeout)
+{
+    if (window.internals)
+        internals.clearMemoryCache();
+
+    const frame = document.createElement("iframe");
+    frame.width = 100;
+    frame.height = 100;
+    frame.src = src;
+    document.body.appendChild(frame);
+    document.body.appendChild(document.createTextNode("\n"));
+
+    return new Promise(resolve => setTimeout(resolve, timeout));
+}
+
+async function test() {
+    // Need to wait long enough for disk cache writes to happen.
+    await addImageFrame(makeCollision("shattered-nocollision-1.pdf"), 1000);
+    await addImageFrame(makeCollision("shattered-nocollision-2.pdf"), 1000);
+    await addImageFrame(makeCollision("shattered-nocollision-1.pdf"), 1000);
+    await addImageFrame(makeCollision("shattered-nocollision-2.pdf"), 1000);
+
+    if (window.testRunner)
+        testRunner.notifyDone();
+}
+test();
+</script>