<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[201468] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/201468">201468</a></dd>
<dt>Author</dt> <dd>bfulgham@apple.com</dd>
<dt>Date</dt> <dd>2016-05-27 13:50:04 -0700 (Fri, 27 May 2016)</dd>
</dl>

<h3>Log Message</h3>
<pre>CSP: Fire 'load' events even when blocking loads via 'frame-src'.
https://bugs.webkit.org/show_bug.cgi?id=153150
&lt;rdar://problem/24383162&gt;

Reviewed by Daniel Bates.

Source/WebCore:

Always fire a load event, even when the load is blocked by CSP rules, so that
attackers cannot gain knowledge about the URL in the frame by blocking the
load and waiting long enough to be sure that a 'load' event would have
fired if the load wasn't blocked.

Inspired by Blink patch:
&lt;https://src.chromium.org/viewvc/blink?view=rev&amp;revision=165743&gt;

Tests: http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html

* loader/PolicyChecker.cpp:
(WebCore::PolicyChecker::checkNavigationPolicy):

LayoutTests:

* TestExpectations: Unskip the cross-origin load test.
* http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load-expected.txt: Update to match
our message format.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestsTestExpectations">trunk/LayoutTests/TestExpectations</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycontentSecurityPolicyframesrccrossoriginloadexpectedtxt">trunk/LayoutTests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load-expected.txt</a></li>
<li><a href="#trunkLayoutTestshttptestssecuritycontentSecurityPolicyframesrccrossoriginloadhtml">trunk/LayoutTests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html</a></li>
<li><a href="#trunkSourceWebCoreChangeLog">trunk/Source/WebCore/ChangeLog</a></li>
<li><a href="#trunkSourceWebCoreloaderPolicyCheckercpp">trunk/Source/WebCore/loader/PolicyChecker.cpp</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (201467 => 201468)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2016-05-27 20:45:08 UTC (rev 201467)
+++ trunk/LayoutTests/ChangeLog        2016-05-27 20:50:04 UTC (rev 201468)
</span><span class="lines">@@ -1,3 +1,15 @@
</span><ins>+2016-05-27  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        CSP: Fire 'load' events even when blocking loads via 'frame-src'.
+        https://bugs.webkit.org/show_bug.cgi?id=153150
+        &lt;rdar://problem/24383162&gt;
+
+        Reviewed by Daniel Bates.
+
+        * TestExpectations: Unskip the cross-origin load test.
+        * http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load-expected.txt: Update to match
+        our message format.
+
</ins><span class="cx"> 2016-05-27  Saam barati  &lt;sbarati@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         ShadowChicken/DebuggerCallFrame don't properly handle when the entry stack frame is a tail deleted frame
</span></span></pre></div>
<a id="trunkLayoutTestsTestExpectations"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/TestExpectations (201467 => 201468)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/TestExpectations        2016-05-27 20:45:08 UTC (rev 201467)
+++ trunk/LayoutTests/TestExpectations        2016-05-27 20:50:04 UTC (rev 201468)
</span><span class="lines">@@ -842,7 +842,6 @@
</span><span class="cx"> webkit.org/b/153148 http/tests/security/contentSecurityPolicy/eval-allowed-in-report-only-mode-and-sends-report.php
</span><span class="cx"> webkit.org/b/153150 http/tests/security/contentSecurityPolicy/1.1/child-src/frame-fires-load-event-when-blocked.html
</span><span class="cx"> webkit.org/b/153150 http/tests/security/contentSecurityPolicy/1.1/child-src/frame-fires-load-event-when-redirect-blocked.html
</span><del>-webkit.org/b/153150 http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html
</del><span class="cx"> webkit.org/b/153152 http/tests/security/contentSecurityPolicy/manifest-src-allowed.html # Needs testRunner.getManifestThen()
</span><span class="cx"> webkit.org/b/153152 http/tests/security/contentSecurityPolicy/manifest-src-blocked.html # Needs testRunner.getManifestThen()
</span><span class="cx"> webkit.org/b/153155 http/tests/security/contentSecurityPolicy/1.1/scripthash-basic-blocked-error-event.html
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycontentSecurityPolicyframesrccrossoriginloadexpectedtxt"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load-expected.txt (201467 => 201468)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load-expected.txt        2016-05-27 20:45:08 UTC (rev 201467)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load-expected.txt        2016-05-27 20:50:04 UTC (rev 201468)
</span><span class="lines">@@ -1,5 +1,4 @@
</span><del>-CONSOLE MESSAGE: line 24: Refused to frame 'https://localhost:8443/security/contentSecurityPolicy/resources/alert-fail.html' because it violates the following Content Security Policy directive: &quot;frame-src 'self' http://localhost:8080&quot;.
-
</del><ins>+CONSOLE MESSAGE: Refused to load https://localhost:8443/security/contentSecurityPolicy/resources/alert-fail.html because it does not appear in the frame-src directive of the Content Security Policy.
</ins><span class="cx"> ALERT: PASS
</span><span class="cx"> ALERT: PASS
</span><span class="cx"> IFrames blocked by CSP should generate a 'load' event, regardless of blocked state. This means they appear to be normal cross-origin loads, thereby not leaking URL information directly to JS.
</span></span></pre></div>
<a id="trunkLayoutTestshttptestssecuritycontentSecurityPolicyframesrccrossoriginloadhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html (201467 => 201468)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html        2016-05-27 20:45:08 UTC (rev 201467)
+++ trunk/LayoutTests/http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html        2016-05-27 20:50:04 UTC (rev 201468)
</span><span class="lines">@@ -1,11 +1,11 @@
</span><span class="cx"> &lt;!DOCTYPE html&gt;
</span><span class="cx"> &lt;html&gt;
</span><span class="cx"> &lt;head&gt;
</span><del>-    &lt;script src=&quot;/js-test-resources/js-test.js&quot;&gt;&lt;/script&gt;
</del><ins>+    &lt;script src=&quot;/js-test-resources/js-test-pre.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx">     &lt;meta http-equiv=&quot;Content-Security-Policy&quot; content=&quot;frame-src 'self' http://localhost:8080&quot;&gt;
</span><span class="cx">     &lt;script&gt;
</span><del>-        window.jsTestIsAsync = true;
-        window.wasPostTestScriptParsed = true;
</del><ins>+        if (window.testRunner)
+            testRunner.waitUntilDone();
</ins><span class="cx">         
</span><span class="cx">         description(&quot;IFrames blocked by CSP should generate a 'load' event, regardless of blocked state. This means they appear to be normal cross-origin loads, thereby not leaking URL information directly to JS.&quot;);
</span><span class="cx"> 
</span><span class="lines">@@ -13,8 +13,10 @@
</span><span class="cx">         function loadEvent() {
</span><span class="cx">             loads++;
</span><span class="cx">             testPassed(&quot;IFrame #&quot; + loads + &quot; generated a 'load' event.&quot;);
</span><del>-            if (loads == 3)
-                finishJSTest();
</del><ins>+            if (loads == 3) {
+                if (window.testRunner)
+                    testRunner.notifyDone();
+            }
</ins><span class="cx">         }
</span><span class="cx">     &lt;/script&gt;
</span><span class="cx"> &lt;/head&gt;
</span><span class="lines">@@ -22,5 +24,6 @@
</span><span class="cx">     &lt;iframe src=&quot;/security/contentSecurityPolicy/resources/alert-pass.html&quot; onload=&quot;loadEvent()&quot;&gt;&lt;/iframe&gt;
</span><span class="cx">     &lt;iframe src=&quot;http://localhost:8080/security/contentSecurityPolicy/resources/alert-pass.html&quot; onload=&quot;loadEvent()&quot;&gt;&lt;/iframe&gt;
</span><span class="cx">     &lt;iframe src=&quot;https://localhost:8443/security/contentSecurityPolicy/resources/alert-fail.html&quot; onload=&quot;loadEvent()&quot;&gt;&lt;/iframe&gt;
</span><ins>+    &lt;script src=&quot;/js-test-resources/js-test-post.js&quot;&gt;&lt;/script&gt;
</ins><span class="cx"> &lt;/body&gt;
</span><span class="cx"> &lt;/html&gt;
</span></span></pre></div>
<a id="trunkSourceWebCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/ChangeLog (201467 => 201468)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/ChangeLog        2016-05-27 20:45:08 UTC (rev 201467)
+++ trunk/Source/WebCore/ChangeLog        2016-05-27 20:50:04 UTC (rev 201468)
</span><span class="lines">@@ -1,3 +1,24 @@
</span><ins>+2016-05-27  Brent Fulgham  &lt;bfulgham@apple.com&gt;
+
+        CSP: Fire 'load' events even when blocking loads via 'frame-src'.
+        https://bugs.webkit.org/show_bug.cgi?id=153150
+        &lt;rdar://problem/24383162&gt;
+
+        Reviewed by Daniel Bates.
+
+        Always fire a load event, even when the load is blocked by CSP rules, so that
+        attackers cannot gain knowledge about the URL in the frame by blocking the
+        load and waiting long enough to be sure that a 'load' event would have
+        fired if the load wasn't blocked.
+
+        Inspired by Blink patch:
+        &lt;https://src.chromium.org/viewvc/blink?view=rev&amp;revision=165743&gt;
+
+        Tests: http/tests/security/contentSecurityPolicy/frame-src-cross-origin-load.html
+
+        * loader/PolicyChecker.cpp:
+        (WebCore::PolicyChecker::checkNavigationPolicy):
+
</ins><span class="cx"> 2016-05-27  Andreas Kling  &lt;akling@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Document abandons its EventTargetData.
</span></span></pre></div>
<a id="trunkSourceWebCoreloaderPolicyCheckercpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebCore/loader/PolicyChecker.cpp (201467 => 201468)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebCore/loader/PolicyChecker.cpp        2016-05-27 20:45:08 UTC (rev 201467)
+++ trunk/Source/WebCore/loader/PolicyChecker.cpp        2016-05-27 20:50:04 UTC (rev 201468)
</span><span class="lines">@@ -98,6 +98,11 @@
</span><span class="cx">     }
</span><span class="cx"> 
</span><span class="cx">     if (!isAllowedByContentSecurityPolicy(request.url(), m_frame.ownerElement(), didReceiveRedirectResponse)) {
</span><ins>+        if (m_frame.ownerElement()) {
+            // Fire a load event (even though we were blocked by CSP) as timing attacks would otherwise
+            // reveal that the frame was blocked. This way, it looks like any other cross-origin page load.
+            m_frame.ownerElement()-&gt;dispatchEvent(Event::create(eventNames().loadEvent, false, false));
+        }
</ins><span class="cx">         function(request, 0, false);
</span><span class="cx">         return;
</span><span class="cx">     }
</span></span></pre>
</div>
</div>

</body>
</html>