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;