Changeset 130150 in webkit
- Timestamp:
- Oct 2, 2012, 4:29:33 AM (13 years ago)
- Location:
- trunk
- Files:
-
- 14 added
- 4 deleted
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r130147 r130150 1 2012-10-02 Mike West <mkwst@chromium.org> 2 3 Add call stacks to Content Security Policy checks when relevant. 4 https://bugs.webkit.org/show_bug.cgi?id=94433 5 6 Reviewed by Adam Barth. 7 8 * http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval-expected.txt: Removed. 9 * http/tests/inspector-enabled/contentSecurityPolicy-blocks-setInterval.html: Removed. 10 * http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout-expected.txt: Removed. 11 * http/tests/inspector-enabled/contentSecurityPolicy-blocks-setTimeout.html: Removed. 12 Moved these tests to http/test/inspector, and rewrote them for consistency. 13 * http/tests/inspector/csp-injected-content-warning-contains-stacktrace-expected.txt: Added. 14 * http/tests/inspector/csp-injected-content-warning-contains-stacktrace.html: Added. 15 * http/tests/inspector/csp-inline-warning-contains-stacktrace-expected.txt: Added. 16 * http/tests/inspector/csp-inline-warning-contains-stacktrace.html: Added. 17 * http/tests/inspector/csp-setInterval-contains-stacktrace-expected.txt: Added. 18 * http/tests/inspector/csp-setInterval-warning-contains-stacktrace.html: Added. 19 * http/tests/inspector/csp-setTimeout-warning-contains-stacktrace-expected.txt: Added. 20 * http/tests/inspector/csp-setTimeout-warning-contains-stacktrace.html: Added. 21 * http/tests/inspector/resources/csp-inline-test.js: Added. 22 (thisTest): 23 * http/tests/inspector/resources/csp-test.js: Added. 24 (test.addMessage): 25 (test): 26 Two new tests for the functionality. 27 * platform/chromium/http/tests/inspector/csp-injected-content-warning-contains-stacktrace-expected.txt: Added. 28 * platform/chromium/http/tests/inspector/csp-inline-warning-contains-stacktrace-expected.txt: Added. 29 * platform/chromium/http/tests/inspector/csp-setInterval-contains-stacktrace-expected.txt: Added. 30 * platform/chromium/http/tests/inspector/csp-setTimeout-warning-contains-stacktrace-expected.txt: Added. 31 The stacktrace looks slightly different under JSC than V8. 32 1 33 2012-10-02 Yoshifumi Inoue <yosin@chromium.org> 2 34 -
trunk/Source/WebCore/ChangeLog
r130149 r130150 1 2012-10-02 Mike West <mkwst@chromium.org> 2 3 Add call stacks to Content Security Policy checks when relevant. 4 https://bugs.webkit.org/show_bug.cgi?id=94433 5 6 Reviewed by Adam Barth. 7 8 Previously, we generated stack traces only for eval-related CSP 9 violations. As it turns out, we can call createScriptCallStack from 10 practically anywhere. This patch takes advantage of that to generate 11 stack traces whenever a warning is logged to the console. If we're in 12 a JavaScript stack, brilliant: we get a detailed warning. If not, the 13 stack trace is empty, and we don't pass it into the console logging 14 method. 15 16 This has the advantage of giving us good developer-facing logging for 17 any and all violations that result from script-based injection of 18 resources. Yay! 19 20 Tests: http/tests/inspector/csp-injected-content-warning-contains-stacktrace.html 21 http/tests/inspector/csp-inline-warning-contains-stacktrace.html 22 http/tests/inspector/csp-setInterval-warning-contains-stacktrace.html 23 http/tests/inspector/csp-setTimeout-warning-contains-stacktrace.html 24 25 * bindings/js/ScheduledAction.cpp: 26 (WebCore::ScheduledAction::create): 27 Replacing the generated stack trace with the current script state, 28 which will enable us to generate the stack trace inside 29 ContentSecurityPolicy::reportViolation if it's relevant. 30 * bindings/v8/ScriptCallStackFactory.cpp: 31 (WebCore::createScriptCallStackForConsole): 32 (WebCore): 33 * bindings/v8/ScriptCallStackFactory.h: 34 (WebCore): 35 Adding a dummy interface to createScriptCallStackForConsole that 36 allows ScriptState to be passed in, which matches JSC's interface. 37 * bindings/v8/custom/V8DOMWindowCustom.cpp: 38 (WebCore::WindowSetTimeoutImpl): 39 * bindings/v8/custom/V8WorkerContextCustom.cpp: 40 (WebCore::SetTimeoutOrInterval): 41 Dropping stack trace from call to ContentSecurityPolicy::allowEval. 42 * page/ContentSecurityPolicy.cpp: 43 (CSPDirectiveList): 44 (WebCore::CSPDirectiveList::reportViolation): 45 (WebCore::CSPDirectiveList::checkEvalAndReportViolation): 46 (WebCore::CSPDirectiveList::allowEval): 47 Piping script state through from CSPDirectiveList::allowEval rather 48 than a full stack trace. 49 (WebCore): 50 (WebCore::isAllowedByAll): 51 (WebCore::isAllowedByAllWithState): 52 (WebCore::ContentSecurityPolicy::allowEval): 53 (WebCore::ContentSecurityPolicy::reportViolation): 54 (WebCore::ContentSecurityPolicy::logToConsole): 55 Piping script state through from ContentSecurityPolicy::allowEval 56 rather than a full stack trace. Now, we can simply generate the 57 stack trace just before logging it, and only pass it into 58 addConsoleMessage if it's non-empty. 59 * page/ContentSecurityPolicy.h: 60 (JSC): 61 (WebCore): 62 Including 'ScriptState.h' to normalize V8 and JSC's JS state objects. 63 1 64 2012-10-02 Pavel Feldman <pfeldman@chromium.org> 2 65 -
trunk/Source/WebCore/bindings/js/ScheduledAction.cpp
r130021 r130150 56 56 CallData callData; 57 57 if (getCallData(v, callData) == CallTypeNone) { 58 RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole(exec)); 59 if (policy && !policy->allowEval(callStack.release())) 58 if (policy && !policy->allowEval(exec)) 60 59 return nullptr; 61 60 String string = v.toString(exec)->value(exec); -
trunk/Source/WebCore/bindings/v8/ScriptCallStackFactory.cpp
r130021 r130150 117 117 } 118 118 119 PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(ScriptState* /* state */) 120 { 121 return createScriptCallStackForConsole(); 122 } 123 119 124 PassRefPtr<ScriptArguments> createScriptArguments(const v8::Arguments& v8arguments, unsigned skipArgumentCount) 120 125 { -
trunk/Source/WebCore/bindings/v8/ScriptCallStackFactory.h
r130021 r130150 52 52 PassRefPtr<ScriptArguments> createScriptArguments(const v8::Arguments& v8arguments, unsigned skipArgumentCount); 53 53 54 // This is just an alias to 'createScriptCallStackForConsole();' for compat with JSC. 55 PassRefPtr<ScriptCallStack> createScriptCallStackForConsole(ScriptState*); 56 54 57 } // namespace WebCore 55 58 -
trunk/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
r130021 r130150 129 129 id = DOMTimer::install(scriptContext, action.release(), timeout, singleShot); 130 130 } else { 131 RefPtr<ScriptCallStack> callStack(createScriptCallStackForConsole()); 132 if (imp->document() && !imp->document()->contentSecurityPolicy()->allowEval(callStack.release())) 131 if (imp->document() && !imp->document()->contentSecurityPolicy()->allowEval()) 133 132 return v8Integer(0, args.GetIsolate()); 134 133 ASSERT(imp->frame()); -
trunk/Source/WebCore/bindings/v8/custom/V8WorkerContextCustom.cpp
r130021 r130150 68 68 if (function->IsString()) { 69 69 if (ContentSecurityPolicy* policy = workerContext->contentSecurityPolicy()) { 70 RefPtr<ScriptCallStack> callStack = createScriptCallStackForConsole(); 71 if (!policy->allowEval(callStack.release())) 70 if (!policy->allowEval()) 72 71 return v8Integer(0, args.GetIsolate()); 73 72 } -
trunk/Source/WebCore/page/ContentSecurityPolicy.cpp
r129572 r130150 40 40 #include "SchemeRegistry.h" 41 41 #include "ScriptCallStack.h" 42 #include "ScriptCallStackFactory.h" 43 #include "ScriptState.h" 42 44 #include "SecurityOrigin.h" 43 45 #include "TextEncoding.h" … … 737 739 bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; 738 740 bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; 739 bool allowEval( PassRefPtr<ScriptCallStack>, ContentSecurityPolicy::ReportingStatus) const;741 bool allowEval(ScriptState*, ContentSecurityPolicy::ReportingStatus) const; 740 742 bool allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const KURL&) const; 741 743 bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ContentSecurityPolicy::ReportingStatus) const; … … 770 772 771 773 SourceListDirective* operativeDirective(SourceListDirective*) const; 772 void reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL = KURL(), const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack>= 0) const;774 void reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL = KURL(), const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), ScriptState* = 0) const; 773 775 774 776 bool checkEval(SourceListDirective*) const; … … 780 782 void setEvalDisabledErrorMessage(const String& errorMessage) { m_evalDisabledErrorMessage = errorMessage; } 781 783 782 bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack>= 0) const;784 bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), ScriptState* = 0) const; 783 785 bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, bool isScript) const; 784 786 bool checkNonceAndReportViolation(NonceDirective*, const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const; … … 844 846 } 845 847 846 void CSPDirectiveList::reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const848 void CSPDirectiveList::reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine, ScriptState* state) const 847 849 { 848 850 String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage; 849 m_policy->reportViolation(directiveText, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, callStack);851 m_policy->reportViolation(directiveText, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine, state); 850 852 } 851 853 … … 884 886 } 885 887 886 bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const888 bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine, ScriptState* state) const 887 889 { 888 890 if (checkEval(directive)) … … 893 895 suffix = " Note that 'script-src' was not explicitly set, so 'default-src' is used as a fallback."; 894 896 895 reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), contextURL, contextLine, callStack);897 reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\"." + suffix + "\n", KURL(), contextURL, contextLine, state); 896 898 if (!m_reportOnly) { 897 899 m_policy->reportBlockedScriptExecutionToInspector(directive->text()); … … 1000 1002 } 1001 1003 1002 bool CSPDirectiveList::allowEval( PassRefPtr<ScriptCallStack> callStack, ContentSecurityPolicy::ReportingStatus reportingStatus) const1004 bool CSPDirectiveList::allowEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const 1003 1005 { 1004 1006 DEFINE_STATIC_LOCAL(String, consoleMessage, (ASCIILiteral("Refused to evaluate script because it violates the following Content Security Policy directive: "))); 1005 1007 return reportingStatus == ContentSecurityPolicy::SendReport ? 1006 checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, String(), WTF::OrdinalNumber::beforeFirst(), callStack) :1008 checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, String(), WTF::OrdinalNumber::beforeFirst(), state) : 1007 1009 checkEval(operativeDirective(m_scriptSrc.get())); 1008 1010 } … … 1346 1348 } 1347 1349 1348 template<bool (CSPDirectiveList::*allowed)( PassRefPtr<ScriptCallStack>,ContentSecurityPolicy::ReportingStatus) const>1349 bool isAllowedByAll WithCallStack(const CSPDirectiveListVector& policies, PassRefPtr<ScriptCallStack> callStack, ContentSecurityPolicy::ReportingStatus reportingStatus)1350 template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatus) const> 1351 bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus) 1350 1352 { 1351 1353 for (size_t i = 0; i < policies.size(); ++i) { 1352 if (!(policies[i].get()->*allowed)(callStack, reportingStatus)) 1354 if (!(policies[i].get()->*allowed)(reportingStatus)) 1355 return false; 1356 } 1357 return true; 1358 } 1359 1360 template<bool (CSPDirectiveList::*allowed)(ScriptState* state, ContentSecurityPolicy::ReportingStatus) const> 1361 bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) 1362 { 1363 for (size_t i = 0; i < policies.size(); ++i) { 1364 if (!(policies[i].get()->*allowed)(state, reportingStatus)) 1353 1365 return false; 1354 1366 } … … 1411 1423 } 1412 1424 1413 bool ContentSecurityPolicy::allowEval( PassRefPtr<ScriptCallStack> callStack, ContentSecurityPolicy::ReportingStatus reportingStatus) const1414 { 1415 return isAllowedByAllWith CallStack<&CSPDirectiveList::allowEval>(m_policies, callStack, reportingStatus);1425 bool ContentSecurityPolicy::allowEval(ScriptState* state, ContentSecurityPolicy::ReportingStatus reportingStatus) const 1426 { 1427 return isAllowedByAllWithState<&CSPDirectiveList::allowEval>(m_policies, state, reportingStatus); 1416 1428 } 1417 1429 … … 1515 1527 } 1516 1528 1517 void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const1518 { 1519 logToConsole(consoleMessage, contextURL, contextLine, callStack);1529 void ContentSecurityPolicy::reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header, const String& contextURL, const WTF::OrdinalNumber& contextLine, ScriptState* state) const 1530 { 1531 logToConsole(consoleMessage, contextURL, contextLine, state); 1520 1532 1521 1533 if (reportURIs.isEmpty()) … … 1613 1625 } 1614 1626 1615 void ContentSecurityPolicy::logToConsole(const String& message, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const 1616 { 1627 void ContentSecurityPolicy::logToConsole(const String& message, const String& contextURL, const WTF::OrdinalNumber& contextLine, ScriptState* state) const 1628 { 1629 RefPtr<ScriptCallStack> callStack; 1630 if (InspectorInstrumentation::consoleAgentEnabled(m_scriptExecutionContext)) { 1631 if (state) 1632 callStack = createScriptCallStackForConsole(state); 1633 else 1634 callStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true); 1635 if (callStack && !callStack->size()) 1636 callStack = 0; 1637 } 1617 1638 m_scriptExecutionContext->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt(), callStack); 1618 1639 } -
trunk/Source/WebCore/page/ContentSecurityPolicy.h
r129525 r130150 28 28 29 29 #include "KURL.h" 30 #include "ScriptState.h" 30 31 #include <wtf/PassOwnPtr.h> 31 32 #include <wtf/RefCounted.h> … … 41 42 42 43 class CSPDirectiveList; 43 class ScriptCallStack;44 44 class DOMStringList; 45 45 class ScriptExecutionContext; … … 81 81 bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 82 82 bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 83 bool allowEval( PassRefPtr<ScriptCallStack>, ReportingStatus = SendReport) const;83 bool allowEval(ScriptState* = 0, ReportingStatus = SendReport) const; 84 84 bool allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const KURL& = KURL()) const; 85 85 bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ReportingStatus = SendReport) const; … … 107 107 void reportInvalidSourceExpression(const String& directiveName, const String& source) const; 108 108 void reportUnrecognizedDirective(const String&) const; 109 void reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack>= 0) const;109 void reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, const Vector<KURL>& reportURIs, const String& header, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), ScriptState* = 0) const; 110 110 111 111 void reportBlockedScriptExecutionToInspector(const String& directiveText) const; … … 120 120 explicit ContentSecurityPolicy(ScriptExecutionContext*); 121 121 122 void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), PassRefPtr<ScriptCallStack>= 0) const;122 void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst(), ScriptState* = 0) const; 123 123 124 124 ScriptExecutionContext* m_scriptExecutionContext;
Note:
See TracChangeset
for help on using the changeset viewer.