Changeset 126852 in webkit
- Timestamp:
- Aug 28, 2012 12:11:28 AM (12 years ago)
- Location:
- trunk
- Files:
-
- 6 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r126850 r126852 1 2012-08-28 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/csp-injected-content-warning-contains-stacktrace-expected.txt: Added. 9 * http/tests/inspector/csp-injected-content-warning-contains-stacktrace.html: Added. 10 * http/tests/inspector/csp-inline-warning-contains-stacktrace-expected.txt: Added. 11 * http/tests/inspector/csp-inline-warning-contains-stacktrace.html: Added. 12 * http/tests/inspector/resources/csp-inline-test.js: Added. 13 (thisTest): 14 * http/tests/inspector/resources/csp-test.js: Added. 15 (test.addMessage): 16 (test): 17 1 18 2012-08-27 Zan Dobersek <zandobersek@gmail.com> 2 19 -
trunk/Source/WebCore/ChangeLog
r126851 r126852 1 2012-08-28 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 23 * bindings/js/ScriptController.cpp: 24 (WebCore::ScriptController::initScript): 25 * bindings/js/ScheduledAction.cpp: 26 (WebCore::ScheduledAction::create): 27 * bindings/v8/V8DOMWindowShell.cpp: 28 (WebCore::V8DOMWindowShell::initContextIfNeeded): 29 * bindings/v8/custom/V8DOMWindowCustom.cpp: 30 (WebCore::WindowSetTimeoutImpl): 31 Dropping stack trace from call to ContentSecurityPolicy::allowEval. 32 * page/ContentSecurityPolicy.cpp: 33 (CSPDirectiveList): 34 (WebCore::CSPDirectiveList::reportViolation): 35 (WebCore::CSPDirectiveList::checkEvalAndReportViolation): 36 (WebCore::CSPDirectiveList::allowEval): 37 No longer piping a stack trace through CSPDirectiveList::allowEval 38 to reportViolation. 39 (WebCore::ContentSecurityPolicy::didReceiveHeader): 40 Dropping stack trace from call to ContentSecurityPolicy::allowEval. 41 (WebCore): 42 (WebCore::isAllowedByAll): 43 (WebCore::ContentSecurityPolicy::allowEval): 44 (WebCore::ContentSecurityPolicy::reportViolation): 45 (WebCore::ContentSecurityPolicy::logToConsole): 46 No longer piping a stack trace through ContentSecurityPolicy down to 47 the point where it would be logged. Instead, we simply generate the 48 stack trace just before logging it, and only pass it to 49 addConsoleMessage if it's non-empty. 50 * page/ContentSecurityPolicy.h: 51 (WebCore): 52 * page/DOMSecurityPolicy.cpp: 53 (WebCore::DOMSecurityPolicy::allowsEval): 54 Dropping stack trace from call to ContentSecurityPolicy::allowEval. 55 1 56 2012-08-27 Andrey Kosyakov <caseq@chromium.org> 2 57 -
trunk/Source/WebCore/bindings/js/ScheduledAction.cpp
r121381 r126852 56 56 CallData callData; 57 57 if (getCallData(v, callData) == CallTypeNone) { 58 RefPtr<ScriptCallStack> callStack(createScriptCallStackForInspector(exec)); 59 if (policy && !policy->allowEval(callStack.release())) 58 if (policy && !policy->allowEval()) 60 59 return nullptr; 61 60 UString string = v.toString(exec)->value(exec); -
trunk/Source/WebCore/bindings/js/ScriptController.cpp
r126837 r126852 223 223 224 224 if (m_frame->document()) 225 windowShell->window()->setEvalEnabled(m_frame->document()->contentSecurityPolicy()->allowEval( 0, ContentSecurityPolicy::SuppressReport));225 windowShell->window()->setEvalEnabled(m_frame->document()->contentSecurityPolicy()->allowEval(ContentSecurityPolicy::SuppressReport)); 226 226 227 227 if (Page* page = m_frame->page()) { -
trunk/Source/WebCore/bindings/v8/V8DOMWindowShell.cpp
r126829 r126852 321 321 322 322 if (m_frame->document()) 323 context->AllowCodeGenerationFromStrings(m_frame->document()->contentSecurityPolicy()->allowEval( 0,ContentSecurityPolicy::SuppressReport));323 context->AllowCodeGenerationFromStrings(m_frame->document()->contentSecurityPolicy()->allowEval(ContentSecurityPolicy::SuppressReport)); 324 324 325 325 m_frame->loader()->client()->didCreateScriptContext(m_context.get(), 0, 0); -
trunk/Source/WebCore/bindings/v8/custom/V8DOMWindowCustom.cpp
r126363 r126852 129 129 id = DOMTimer::install(scriptContext, action.release(), timeout, singleShot); 130 130 } else { 131 RefPtr<ScriptCallStack> callStack(createScriptCallStackForInspector()); 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/page/ContentSecurityPolicy.cpp
r126785 r126852 39 39 #include "SchemeRegistry.h" 40 40 #include "ScriptCallStack.h" 41 #include "ScriptCallStackFactory.h" 41 42 #include "SecurityOrigin.h" 42 43 #include "TextEncoding.h" … … 711 712 bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; 712 713 bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::ReportingStatus) const; 713 bool allowEval( PassRefPtr<ScriptCallStack>,ContentSecurityPolicy::ReportingStatus) const;714 bool allowEval(ContentSecurityPolicy::ReportingStatus) const; 714 715 bool allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const KURL&) const; 715 716 bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ContentSecurityPolicy::ReportingStatus) const; … … 743 744 744 745 SourceListDirective* operativeDirective(SourceListDirective*) const; 745 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;746 void reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL = KURL(), const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst()) const; 746 747 747 748 bool checkEval(SourceListDirective*) const; … … 751 752 bool checkMediaType(MediaListDirective*, const String& type, const String& typeAttribute) const; 752 753 753 bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst() , PassRefPtr<ScriptCallStack> = 0) const;754 bool checkEvalAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst()) const; 754 755 bool checkInlineAndReportViolation(SourceListDirective*, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const; 755 756 bool checkNonceAndReportViolation(NonceDirective*, const String& nonce, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const; … … 806 807 } 807 808 808 void CSPDirectiveList::reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine , PassRefPtr<ScriptCallStack> callStack) const809 void CSPDirectiveList::reportViolation(const String& directiveText, const String& consoleMessage, const KURL& blockedURL, const String& contextURL, const WTF::OrdinalNumber& contextLine) const 809 810 { 810 811 String message = m_reportOnly ? "[Report Only] " + consoleMessage : consoleMessage; 811 m_policy->reportViolation(directiveText, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine , callStack);812 m_policy->reportViolation(directiveText, message, blockedURL, m_reportURIs, m_header, contextURL, contextLine); 812 813 } 813 814 … … 846 847 } 847 848 848 bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine , PassRefPtr<ScriptCallStack> callStack) const849 bool CSPDirectiveList::checkEvalAndReportViolation(SourceListDirective* directive, const String& consoleMessage, const String& contextURL, const WTF::OrdinalNumber& contextLine) const 849 850 { 850 851 if (checkEval(directive)) 851 852 return true; 852 reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\".\n", KURL(), contextURL, contextLine , callStack);853 reportViolation(directive->text(), consoleMessage + "\"" + directive->text() + "\".\n", KURL(), contextURL, contextLine); 853 854 return denyIfEnforcingPolicy(); 854 855 } … … 938 939 } 939 940 940 bool CSPDirectiveList::allowEval( PassRefPtr<ScriptCallStack> callStack,ContentSecurityPolicy::ReportingStatus reportingStatus) const941 bool CSPDirectiveList::allowEval(ContentSecurityPolicy::ReportingStatus reportingStatus) const 941 942 { 942 943 DEFINE_STATIC_LOCAL(String, consoleMessage, ("Refused to evaluate script because it violates the following Content Security Policy directive: ")); 943 944 return reportingStatus == ContentSecurityPolicy::SendReport ? 944 checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, String(), WTF::OrdinalNumber::beforeFirst() , callStack) :945 checkEvalAndReportViolation(operativeDirective(m_scriptSrc.get()), consoleMessage, String(), WTF::OrdinalNumber::beforeFirst()) : 945 946 checkEval(operativeDirective(m_scriptSrc.get())); 946 947 } … … 1258 1259 } 1259 1260 1260 if (!allowEval( 0,SuppressReport))1261 if (!allowEval(SuppressReport)) 1261 1262 m_scriptExecutionContext->disableEval(); 1262 1263 } … … 1277 1278 } 1278 1279 1279 template<bool (CSPDirectiveList::*allowed)( PassRefPtr<ScriptCallStack>,ContentSecurityPolicy::ReportingStatus) const>1280 bool isAllowedByAll WithCallStack(const CSPDirectiveListVector& policies, PassRefPtr<ScriptCallStack> callStack, ContentSecurityPolicy::ReportingStatus reportingStatus)1280 template<bool (CSPDirectiveList::*allowed)( ContentSecurityPolicy::ReportingStatus) const> 1281 bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolicy::ReportingStatus reportingStatus) 1281 1282 { 1282 1283 for (size_t i = 0; i < policies.size(); ++i) { 1283 if (!(policies[i].get()->*allowed)( callStack,reportingStatus))1284 if (!(policies[i].get()->*allowed)(reportingStatus)) 1284 1285 return false; 1285 1286 } … … 1342 1343 } 1343 1344 1344 bool ContentSecurityPolicy::allowEval( PassRefPtr<ScriptCallStack> callStack,ContentSecurityPolicy::ReportingStatus reportingStatus) const1345 { 1346 return isAllowedByAll WithCallStack<&CSPDirectiveList::allowEval>(m_policies, callStack, reportingStatus);1345 bool ContentSecurityPolicy::allowEval(ContentSecurityPolicy::ReportingStatus reportingStatus) const 1346 { 1347 return isAllowedByAll<&CSPDirectiveList::allowEval>(m_policies, reportingStatus); 1347 1348 } 1348 1349 … … 1437 1438 } 1438 1439 1439 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) const1440 { 1441 logToConsole(consoleMessage, contextURL, contextLine , callStack);1440 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) const 1441 { 1442 logToConsole(consoleMessage, contextURL, contextLine); 1442 1443 1443 1444 if (reportURIs.isEmpty()) … … 1523 1524 } 1524 1525 1525 void ContentSecurityPolicy::logToConsole(const String& message, const String& contextURL, const WTF::OrdinalNumber& contextLine, PassRefPtr<ScriptCallStack> callStack) const 1526 { 1527 m_scriptExecutionContext->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt(), callStack); 1528 } 1529 1530 } 1526 void ContentSecurityPolicy::logToConsole(const String& message, const String& contextURL, const WTF::OrdinalNumber& contextLine) const 1527 { 1528 RefPtr<ScriptCallStack> callStack; 1529 if (InspectorInstrumentation::hasFrontends()) 1530 callStack = createScriptCallStack(ScriptCallStack::maxCallStackSizeToCapture, true); 1531 m_scriptExecutionContext->addConsoleMessage(JSMessageSource, LogMessageType, ErrorMessageLevel, message, contextURL, contextLine.oneBasedInt(), (callStack && callStack->size() > 0) ? callStack : 0); 1532 } 1533 1534 } -
trunk/Source/WebCore/page/ContentSecurityPolicy.h
r125772 r126852 41 41 42 42 class CSPDirectiveList; 43 class ScriptCallStack;44 43 class DOMStringList; 45 44 class ScriptExecutionContext; … … 80 79 bool allowInlineScript(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 81 80 bool allowInlineStyle(const String& contextURL, const WTF::OrdinalNumber& contextLine, ReportingStatus = SendReport) const; 82 bool allowEval( PassRefPtr<ScriptCallStack>,ReportingStatus = SendReport) const;81 bool allowEval(ReportingStatus = SendReport) const; 83 82 bool allowScriptNonce(const String& nonce, const String& contextURL, const WTF::OrdinalNumber& contextLine, const KURL& = KURL()) const; 84 83 bool allowPluginType(const String& type, const String& typeAttribute, const KURL&, ReportingStatus = SendReport) const; … … 105 104 void reportInvalidSourceExpression(const String& directiveName, const String& source) const; 106 105 void reportUnrecognizedDirective(const String&) const; 107 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;106 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()) const; 108 107 109 108 const KURL& url() const; … … 115 114 explicit ContentSecurityPolicy(ScriptExecutionContext*); 116 115 117 void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst() , PassRefPtr<ScriptCallStack> = 0) const;116 void logToConsole(const String& message, const String& contextURL = String(), const WTF::OrdinalNumber& contextLine = WTF::OrdinalNumber::beforeFirst()) const; 118 117 119 118 ScriptExecutionContext* m_scriptExecutionContext; -
trunk/Source/WebCore/page/DOMSecurityPolicy.cpp
r125983 r126852 121 121 return true; 122 122 123 return scriptExecutionContext()->contentSecurityPolicy()->allowEval( 0,ContentSecurityPolicy::SuppressReport);123 return scriptExecutionContext()->contentSecurityPolicy()->allowEval(ContentSecurityPolicy::SuppressReport); 124 124 } 125 125
Note: See TracChangeset
for help on using the changeset viewer.