Title: [117826] trunk
Revision
117826
Author
[email protected]
Date
2012-05-21 16:00:46 -0700 (Mon, 21 May 2012)

Log Message

Source/WebCore: Improving console error for CSP-blocked  `setTimeout` and `setInterval` evaluation.
https://bugs.webkit.org/show_bug.cgi?id=86943

Patch by Mike West <[email protected]> on 2012-05-21
Reviewed by Adam Barth.

If the inspector is open, a stack trace is generated before calling
ContentSecurityPolicy::allowEval, and passed through to
ContentSecurityPolicy::reportViolation for use in the console message.

Test: http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval.html
      http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout.html

* bindings/js/ScheduledAction.cpp:
(WebCore::ScheduledAction::create):
* bindings/v8/custom/V8DOMWindowCustom.cpp:
(WebCore::WindowSetTimeoutImpl):
* page/ContentSecurityPolicy.cpp:
(CSPDirectiveList):
(WebCore::CSPDirectiveList::reportViolation):
(WebCore::CSPDirectiveList::checkEvalAndReportViolation):
(WebCore::CSPDirectiveList::allowEval):
(WebCore):
(WebCore::isAllowedByAllWithCallStack):
(WebCore::isAllowedByAllWithURL):
(WebCore::ContentSecurityPolicy::allowEval):
(WebCore::ContentSecurityPolicy::allowScriptFromSource):
(WebCore::ContentSecurityPolicy::allowObjectFromSource):
(WebCore::ContentSecurityPolicy::allowChildFrameFromSource):
(WebCore::ContentSecurityPolicy::allowImageFromSource):
(WebCore::ContentSecurityPolicy::allowStyleFromSource):
(WebCore::ContentSecurityPolicy::allowFontFromSource):
(WebCore::ContentSecurityPolicy::allowMediaFromSource):
(WebCore::ContentSecurityPolicy::allowConnectToSource):
* page/ContentSecurityPolicy.h:
(WebCore):

LayoutTests: Blocking `setTimeout` and `setInterval` evaluation with CSP should include a stack trace in the console warning.
https://bugs.webkit.org/show_bug.cgi?id=86943

Patch by Mike West <[email protected]> on 2012-05-21
Reviewed by Adam Barth.

* http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval-expected.txt: Added.
* http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval.html: Added.
* http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout-expected.txt: Added.
* http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (117825 => 117826)


--- trunk/LayoutTests/ChangeLog	2012-05-21 22:57:49 UTC (rev 117825)
+++ trunk/LayoutTests/ChangeLog	2012-05-21 23:00:46 UTC (rev 117826)
@@ -1,3 +1,15 @@
+2012-05-21  Mike West  <[email protected]>
+
+        Blocking `setTimeout` and `setInterval` evaluation with CSP should include a stack trace in the console warning.
+        https://bugs.webkit.org/show_bug.cgi?id=86943
+
+        Reviewed by Adam Barth.
+
+        * http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval-expected.txt: Added.
+        * http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval.html: Added.
+        * http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout-expected.txt: Added.
+        * http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout.html: Added.
+
 2012-05-21  Levi Weintraub  <[email protected]>
 
         Unreviewed gardening. Updating expectations after r117815.

Added: trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval-expected.txt (0 => 117826)


--- trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval-expected.txt	2012-05-21 23:00:46 UTC (rev 117826)
@@ -0,0 +1,8 @@
+CONSOLE MESSAGE: Refused to evaluate script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+
+Tests that a CSP-blocked `setInterval` call generates a console message with a stack trace (https://bugs.webkit.org/show_bug.cgi?id=86943). This should be followed by a rejection notice tied to line 18.
+
+PASS: Return value for blocked setInterval is 0
+Refused to evaluate script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+ contentSecurityPolicy-blocks-setInterval.html:18
+

Added: trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval.html (0 => 117826)


--- trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval.html	2012-05-21 23:00:46 UTC (rev 117826)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="X-WebKit-CSP" content="script-src 'self' 'unsafe-inline'">
+<script src=""
+<script src=""
+<script>
+function log(text) {
+    document.body.appendChild(document.createTextNode(text));
+    document.body.appendChild(document.createElement('br'));
+}
+function onload() {
+  if (window.layoutTestController) {
+      layoutTestController.waitUntilDone();
+      layoutTestController.showWebInspector();
+  }
+
+  var id = setInterval("log('FAIL')", 0);
+  if (id != 0)
+      log('FAIL: Return value for string (should be 0): ' + id);
+  else
+      log('PASS: Return value for blocked setInterval is 0');
+
+  runTest();
+}
+
+function test() {
+    InspectorTest.dumpConsoleMessages();
+    InspectorTest.completeTest();
+}
+</script>
+</head>
+<body _onload_="onload();">
+    <p>
+        Tests that a CSP-blocked `setInterval` call generates a console message
+        with a stack trace (https://bugs.webkit.org/show_bug.cgi?id=86943). This
+        should be followed by a rejection notice tied to line 18.
+    </p>
+</body>
+</html>

Added: trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout-expected.txt (0 => 117826)


--- trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout-expected.txt	2012-05-21 23:00:46 UTC (rev 117826)
@@ -0,0 +1,8 @@
+CONSOLE MESSAGE: Refused to evaluate script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+
+Tests that a CSP-blocked `setTimeout` call generates a console message with a stack trace (https://bugs.webkit.org/show_bug.cgi?id=86943). This should be followed by a rejection notice tied to line 18.
+
+PASS: Return value for blocked setTimeout is 0
+Refused to evaluate script because it violates the following Content Security Policy directive: "script-src 'self' 'unsafe-inline'".
+ contentSecurityPolicy-blocks-setTimeout.html:18
+

Added: trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout.html (0 => 117826)


--- trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout.html	                        (rev 0)
+++ trunk/LayoutTests/http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout.html	2012-05-21 23:00:46 UTC (rev 117826)
@@ -0,0 +1,40 @@
+<!DOCTYPE html>
+<html>
+<head>
+<meta http-equiv="X-WebKit-CSP" content="script-src 'self' 'unsafe-inline'">
+<script src=""
+<script src=""
+<script>
+function log(text) {
+    document.body.appendChild(document.createTextNode(text));
+    document.body.appendChild(document.createElement('br'));
+}
+function onload() {
+  if (window.layoutTestController) {
+      layoutTestController.waitUntilDone();
+      layoutTestController.showWebInspector();
+  }
+
+  var id = setTimeout("log('FAIL')", 0);
+  if (id != 0)
+      log('FAIL: Return value for string (should be 0): ' + id);
+  else
+      log('PASS: Return value for blocked setTimeout is 0');
+
+  runTest();
+}
+
+function test() {
+    InspectorTest.dumpConsoleMessages();
+    InspectorTest.completeTest();
+}
+</script>
+</head>
+<body _onload_="onload();">
+    <p>
+        Tests that a CSP-blocked `setTimeout` call generates a console message
+        with a stack trace (https://bugs.webkit.org/show_bug.cgi?id=86943). This
+        should be followed by a rejection notice tied to line 18.
+    </p>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (117825 => 117826)


--- trunk/Source/WebCore/ChangeLog	2012-05-21 22:57:49 UTC (rev 117825)
+++ trunk/Source/WebCore/ChangeLog	2012-05-21 23:00:46 UTC (rev 117826)
@@ -1,3 +1,41 @@
+2012-05-21  Mike West  <[email protected]>
+
+        Improving console error for CSP-blocked  `setTimeout` and `setInterval` evaluation.
+        https://bugs.webkit.org/show_bug.cgi?id=86943
+
+        Reviewed by Adam Barth.
+
+        If the inspector is open, a stack trace is generated before calling
+        ContentSecurityPolicy::allowEval, and passed through to
+        ContentSecurityPolicy::reportViolation for use in the console message.
+
+        Test: http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval.html
+              http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout.html
+
+        * bindings/js/ScheduledAction.cpp:
+        (WebCore::ScheduledAction::create):
+        * bindings/v8/custom/V8DOMWindowCustom.cpp:
+        (WebCore::WindowSetTimeoutImpl):
+        * page/ContentSecurityPolicy.cpp:
+        (CSPDirectiveList):
+        (WebCore::CSPDirectiveList::reportViolation):
+        (WebCore::CSPDirectiveList::checkEvalAndReportViolation):
+        (WebCore::CSPDirectiveList::allowEval):
+        (WebCore):
+        (WebCore::isAllowedByAllWithCallStack):
+        (WebCore::isAllowedByAllWithURL):
+        (WebCore::ContentSecurityPolicy::allowEval):
+        (WebCore::ContentSecurityPolicy::allowScriptFromSource):
+        (WebCore::ContentSecurityPolicy::allowObjectFromSource):
+        (WebCore::ContentSecurityPolicy::allowChildFrameFromSource):
+        (WebCore::ContentSecurityPolicy::allowImageFromSource):
+        (WebCore::ContentSecurityPolicy::allowStyleFromSource):
+        (WebCore::ContentSecurityPolicy::allowFontFromSource):
+        (WebCore::ContentSecurityPolicy::allowMediaFromSource):
+        (WebCore::ContentSecurityPolicy::allowConnectToSource):
+        * page/ContentSecurityPolicy.h:
+        (WebCore):
+
 2012-05-21  Antoine Labour  <[email protected]>
 
         Don't force rendering in finishAllRendering

Modified: trunk/Source/WebCore/bindings/js/ScheduledAction.cpp (117825 => 117826)


--- trunk/Source/WebCore/bindings/js/ScheduledAction.cpp	2012-05-21 22:57:49 UTC (rev 117825)
+++ trunk/Source/WebCore/bindings/js/ScheduledAction.cpp	2012-05-21 23:00:46 UTC (rev 117826)
@@ -32,6 +32,8 @@
 #include "JSDOMBinding.h"
 #include "JSDOMWindow.h"
 #include "JSMainThreadExecState.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallStackFactory.h"
 #include "ScriptController.h"
 #include "ScriptExecutionContext.h"
 #include "ScriptSourceCode.h"
@@ -53,7 +55,8 @@
     JSValue v = exec->argument(0);
     CallData callData;
     if (getCallData(v, callData) == CallTypeNone) {
-        if (policy && !policy->allowEval())
+        RefPtr<ScriptCallStack> callStack(createScriptCallStackForInspector(exec));
+        if (policy && !policy->allowEval(callStack.release()))
             return nullptr;
         UString string = v.toString(exec)->value(exec);
         if (exec->hadException())

Modified: trunk/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp (117825 => 117826)


--- trunk/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp	2012-05-21 22:57:49 UTC (rev 117825)
+++ trunk/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp	2012-05-21 23:00:46 UTC (rev 117826)
@@ -48,6 +48,8 @@
 #include "Page.h"
 #include "PlatformScreen.h"
 #include "ScheduledAction.h"
+#include "ScriptCallStack.h"
+#include "ScriptCallStackFactory.h"
 #include "ScriptSourceCode.h"
 #include "SerializedScriptValue.h"
 #include "Settings.h"
@@ -129,7 +131,8 @@
 
         id = DOMTimer::install(scriptContext, action.release(), timeout, singleShot);
     } else {
-        if (imp->document() && !imp->document()->contentSecurityPolicy()->allowEval())
+        RefPtr<ScriptCallStack> callStack(createScriptCallStackForInspector());
+        if (imp->document() && !imp->document()->contentSecurityPolicy()->allowEval(callStack.release()))
             return v8::Integer::New(0);
         id = DOMTimer::install(scriptContext, adoptPtr(new ScheduledAction(V8Proxy::context(imp->frame()), functionString)), timeout, singleShot);
     }

Modified: trunk/Source/WebCore/page/ContentSecurityPolicy.cpp (117825 => 117826)


--- trunk/Source/WebCore/page/ContentSecurityPolicy.cpp	2012-05-21 22:57:49 UTC (rev 117825)
+++ trunk/Source/WebCore/page/ContentSecurityPolicy.cpp	2012-05-21 23:00:46 UTC (rev 117826)
@@ -494,7 +494,7 @@
     bool allowInlineEventHandlers() const;
     bool allowInlineScript() const;
     bool allowInlineStyle() const;
-    bool allowEval() const;
+    bool allowEval(PassRefPtr<ScriptCallStack>) const;
 
     bool allowScriptFromSource(const KURL&) const;
     bool allowObjectFromSource(const KURL&) const;
@@ -518,12 +518,12 @@
     PassOwnPtr<CSPDirective> createCSPDirective(const String& name, const String& value);
 
     CSPDirective* operativeDirective(CSPDirective*) const;
-    void reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL = KURL()) const;
+    void reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL = KURL(), PassRefPtr<ScriptCallStack> = 0) const;
     void logUnrecognizedDirective(const String& name) const;
     bool checkEval(CSPDirective*) const;
 
     bool checkInlineAndReportViolation(CSPDirective*, const String& consoleMessage) const;
-    bool checkEvalAndReportViolation(CSPDirective*, const String& consoleMessage) const;
+    bool checkEvalAndReportViolation(CSPDirective*, const String& consoleMessage, PassRefPtr<ScriptCallStack>) const;
     bool checkSourceAndReportViolation(CSPDirective*, const KURL&, const String& type) const;
 
     bool denyIfEnforcingPolicy() const { return m_reportOnly; }
@@ -575,10 +575,10 @@
     return policy.release();
 }
 
-void CSPDirectiveList::reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL) const
+void CSPDirectiveList::reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, PassRefPtr<ScriptCallStack> callStack) const
 {
     String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage;
-    m_scriptExecutionContext->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message);
+    m_scriptExecutionContext->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, String(), 0, callStack);
 
     if (m_reportURIs.isEmpty())
         return;
@@ -646,11 +646,11 @@
     return denyIfEnforcingPolicy();
 }
 
-bool CSPDirectiveList::checkEvalAndReportViolation(CSPDirective* directive, const String& consoleMessage) const
+bool CSPDirectiveList::checkEvalAndReportViolation(CSPDirective* directive, const String& consoleMessage, PassRefPtr<ScriptCallStack> callStack) const
 {
     if (checkEval(directive))
         return true;
-    reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\".\n");
+    reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\".\n", KURL(), callStack);
     return denyIfEnforcingPolicy();
 }
 
@@ -687,10 +687,10 @@
     return checkInlineAndReportViolation(operativeDirective(m_styleSrc.get()), consoleMessage);
 }
 
-bool CSPDirectiveList::allowEval() const
+bool CSPDirectiveList::allowEval(PassRefPtr<ScriptCallStack> callStack) const
 {
     DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate script because it violates the following Content Security Policy directive: "));
-    return checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage);
+    return checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, callStack);
 }
 
 bool CSPDirectiveList::allowScriptFromSource(const KURL& url) const
@@ -933,8 +933,18 @@
     return true;
 }
 
+template<bool (CSPDirectiveList::*allowed)(PassRefPtr<ScriptCallStack>) const>
+bool isAllowedByAllWithCallStack(const CSPDirectiveListVector& policies, PassRefPtr<ScriptCallStack> callStack)
+{
+    for (size_t i = 0; i < policies.size(); ++i) {
+        if (!(policies[i].get()->*allowed)(callStack))
+            return false;
+    }
+    return true;
+}
+
 template<bool (CSPDirectiveList::*allowFromURL)(const KURL&) const>
-bool isAllowedByAll(const CSPDirectiveListVector& policies, const KURL& url)
+bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& url)
 {
     for (size_t i = 0; i < policies.size(); ++i) {
         if (!(policies[i].get()->*allowFromURL)(url))
@@ -965,49 +975,49 @@
     return isAllowedByAll<&CSPDirectiveList::allowInlineStyle>(m_policies);
 }
 
-bool ContentSecurityPolicy::allowEval() const
+bool ContentSecurityPolicy::allowEval(PassRefPtr<ScriptCallStack> callStack) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowEval>(m_policies);
+    return isAllowedByAllWithCallStack<&CSPDirectiveList::allowEval>(m_policies, callStack);
 }
 
 bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowScriptFromSource>(m_policies, url);
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_policies, url);
 }
 
 bool ContentSecurityPolicy::allowObjectFromSource(const KURL& url) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowObjectFromSource>(m_policies, url);
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowObjectFromSource>(m_policies, url);
 }
 
 bool ContentSecurityPolicy::allowChildFrameFromSource(const KURL& url) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowChildFrameFromSource>(m_policies, url);
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowChildFrameFromSource>(m_policies, url);
 }
 
 bool ContentSecurityPolicy::allowImageFromSource(const KURL& url) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowImageFromSource>(m_policies, url);
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowImageFromSource>(m_policies, url);
 }
 
 bool ContentSecurityPolicy::allowStyleFromSource(const KURL& url) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowStyleFromSource>(m_policies, url);
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowStyleFromSource>(m_policies, url);
 }
 
 bool ContentSecurityPolicy::allowFontFromSource(const KURL& url) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowFontFromSource>(m_policies, url);
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowFontFromSource>(m_policies, url);
 }
 
 bool ContentSecurityPolicy::allowMediaFromSource(const KURL& url) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowMediaFromSource>(m_policies, url);
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowMediaFromSource>(m_policies, url);
 }
 
 bool ContentSecurityPolicy::allowConnectToSource(const KURL& url) const
 {
-    return isAllowedByAll<&CSPDirectiveList::allowConnectToSource>(m_policies, url);
+    return isAllowedByAllWithURL<&CSPDirectiveList::allowConnectToSource>(m_policies, url);
 }
 
 }

Modified: trunk/Source/WebCore/page/ContentSecurityPolicy.h (117825 => 117826)


--- trunk/Source/WebCore/page/ContentSecurityPolicy.h	2012-05-21 22:57:49 UTC (rev 117825)
+++ trunk/Source/WebCore/page/ContentSecurityPolicy.h	2012-05-21 23:00:46 UTC (rev 117826)
@@ -34,6 +34,7 @@
 namespace WebCore {
 
 class CSPDirectiveList;
+class ScriptCallStack;
 class ScriptExecutionContext;
 class KURL;
 
@@ -65,7 +66,7 @@
     bool allowInlineEventHandlers() const;
     bool allowInlineScript() const;
     bool allowInlineStyle() const;
-    bool allowEval() const;
+    bool allowEval(PassRefPtr<ScriptCallStack>) const;
 
     bool allowScriptFromSource(const KURL&) const;
     bool allowObjectFromSource(const KURL&) const;
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to