Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(375)

Side by Side Diff: Source/core/frame/csp/ContentSecurityPolicy.cpp

Issue 554303002: CSP: Separate more parse-time side-effects. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/frame/csp/ContentSecurityPolicy.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2011 Google, Inc. All rights reserved. 2 * Copyright (C) 2011 Google, Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 , m_sandboxMask(0) 139 , m_sandboxMask(0)
140 , m_referrerPolicy(ReferrerPolicyDefault) 140 , m_referrerPolicy(ReferrerPolicyDefault)
141 { 141 {
142 } 142 }
143 143
144 void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext() 144 void ContentSecurityPolicy::applyPolicySideEffectsToExecutionContext()
145 { 145 {
146 // Ensure that 'self' processes correctly. 146 // Ensure that 'self' processes correctly.
147 m_selfSource = adoptPtr(new CSPSource(this, securityOrigin()->protocol(), se curityOrigin()->host(), securityOrigin()->port(), String(), false, false)); 147 m_selfSource = adoptPtr(new CSPSource(this, securityOrigin()->protocol(), se curityOrigin()->host(), securityOrigin()->port(), String(), false, false));
148 148
149 // If we're in a Document, set the referrer policy and sandbox flags. 149 // If we're in a Document, set the referrer policy and sandbox flags, then d ump all the
150 // parsing error messages, then poke at histograms.
150 if (Document* document = this->document()) { 151 if (Document* document = this->document()) {
151 document->enforceSandboxFlags(m_sandboxMask); 152 document->enforceSandboxFlags(m_sandboxMask);
152 if (didSetReferrerPolicy()) 153 if (didSetReferrerPolicy())
153 document->setReferrerPolicy(m_referrerPolicy); 154 document->setReferrerPolicy(m_referrerPolicy);
155
156 for (ConsoleMessageVector::const_iterator iter = m_consoleMessages.begin (); iter != m_consoleMessages.end(); ++iter)
157 executionContext()->addConsoleMessage(*iter);
158 m_consoleMessages.clear();
159
160 for (CSPDirectiveListVector::const_iterator iter = m_policies.begin(); i ter != m_policies.end(); ++iter)
161 UseCounter::count(*document, getUseCounterType((*iter)->headerType() ));
154 } 162 }
155 163
156 // We disable 'eval()' even in the case of report-only policies, and rely on the check in the 164 // We disable 'eval()' even in the case of report-only policies, and rely on the check in the
157 // V8Initializer::codeGenerationCheckCallbackInMainThread callback to determ ine whether the 165 // V8Initializer::codeGenerationCheckCallbackInMainThread callback to determ ine whether the
158 // call should execute or not. 166 // call should execute or not.
159 if (!m_disableEvalErrorMessage.isNull()) 167 if (!m_disableEvalErrorMessage.isNull())
160 executionContext()->disableEval(m_disableEvalErrorMessage); 168 executionContext()->disableEval(m_disableEvalErrorMessage);
161 } 169 }
162 170
163 ContentSecurityPolicy::~ContentSecurityPolicy() 171 ContentSecurityPolicy::~ContentSecurityPolicy()
(...skipping 30 matching lines...) Expand all
194 { 202 {
195 addPolicyFromHeaderValue(header, type, source); 203 addPolicyFromHeaderValue(header, type, source);
196 204
197 // FIXME: This ought to be a step distinct from didReceiveHeader(). https:// crbug.com/411889 205 // FIXME: This ought to be a step distinct from didReceiveHeader(). https:// crbug.com/411889
198 if (sideEffectDisposition == ApplySideEffectsToExecutionContext) 206 if (sideEffectDisposition == ApplySideEffectsToExecutionContext)
199 applyPolicySideEffectsToExecutionContext(); 207 applyPolicySideEffectsToExecutionContext();
200 } 208 }
201 209
202 void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Conte ntSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source) 210 void ContentSecurityPolicy::addPolicyFromHeaderValue(const String& header, Conte ntSecurityPolicyHeaderType type, ContentSecurityPolicyHeaderSource source)
203 { 211 {
204 Document* document = this->document(); 212 if (source == ContentSecurityPolicyHeaderSourceMeta && type == ContentSecuri tyPolicyHeaderTypeReport && experimentalFeaturesEnabled()) {
205 if (document) { 213 reportReportOnlyInMeta(header);
206 UseCounter::count(*document, getUseCounterType(type)); 214 return;
207
208 // CSP 1.1 defines report-only in a <meta> element as invalid. Measure f or now, disable in experimental mode.
209 if (source == ContentSecurityPolicyHeaderSourceMeta && type == ContentSe curityPolicyHeaderTypeReport) {
210 UseCounter::count(*document, UseCounter::ContentSecurityPolicyReport OnlyInMeta);
211 if (experimentalFeaturesEnabled()) {
212 reportReportOnlyInMeta(header);
213 return;
214 }
215 }
216 } 215 }
217 216
218 Vector<UChar> characters; 217 Vector<UChar> characters;
219 header.appendTo(characters); 218 header.appendTo(characters);
220 219
221 const UChar* begin = characters.data(); 220 const UChar* begin = characters.data();
222 const UChar* end = begin + characters.size(); 221 const UChar* end = begin + characters.size();
223 222
224 // RFC2616, section 4.2 specifies that headers appearing multiple times can 223 // RFC2616, section 4.2 specifies that headers appearing multiple times can
225 // be combined with a comma. Walk the header string, and parse each comma 224 // be combined with a comma. Walk the header string, and parse each comma
(...skipping 447 matching lines...) Expand 10 before | Expand all | Expand 10 after
673 return; 672 return;
674 673
675 RefPtr<FormData> report = FormData::create(stringifiedReport.utf8()); 674 RefPtr<FormData> report = FormData::create(stringifiedReport.utf8());
676 675
677 for (size_t i = 0; i < reportURIs.size(); ++i) 676 for (size_t i = 0; i < reportURIs.size(); ++i)
678 PingLoader::sendViolationReport(frame, reportURIs[i], report, PingLoader ::ContentSecurityPolicyViolationReport); 677 PingLoader::sendViolationReport(frame, reportURIs[i], report, PingLoader ::ContentSecurityPolicyViolationReport);
679 678
680 didSendViolationReport(stringifiedReport); 679 didSendViolationReport(stringifiedReport);
681 } 680 }
682 681
683 void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) co nst 682 void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue)
684 { 683 {
685 logToConsole("The 'referrer' Content Security Policy directive has the inval id value \"" + invalidValue + "\". Valid values are \"always\", \"default\", \"n ever\", and \"origin\"."); 684 logToConsole("The 'referrer' Content Security Policy directive has the inval id value \"" + invalidValue + "\". Valid values are \"always\", \"default\", \"n ever\", and \"origin\".");
686 } 685 }
687 686
688 void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header) const 687 void ContentSecurityPolicy::reportReportOnlyInMeta(const String& header)
689 { 688 {
690 logToConsole("The report-only Content Security Policy '" + header + "' was d elivered via a <meta> element, which is disallowed. The policy has been ignored. "); 689 logToConsole("The report-only Content Security Policy '" + header + "' was d elivered via a <meta> element, which is disallowed. The policy has been ignored. ");
691 } 690 }
692 691
693 void ContentSecurityPolicy::reportMetaOutsideHead(const String& header) const 692 void ContentSecurityPolicy::reportMetaOutsideHead(const String& header)
694 { 693 {
695 logToConsole("The Content Security Policy '" + header + "' was delivered via a <meta> element outside the document's <head>, which is disallowed. The policy has been ignored."); 694 logToConsole("The Content Security Policy '" + header + "' was delivered via a <meta> element outside the document's <head>, which is disallowed. The policy has been ignored.");
696 } 695 }
697 696
698 void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name) const 697 void ContentSecurityPolicy::reportInvalidInReportOnly(const String& name)
699 { 698 {
700 logToConsole("The Content Security Policy directive '" + name + "' is ignore d when delivered in a report-only policy."); 699 logToConsole("The Content Security Policy directive '" + name + "' is ignore d when delivered in a report-only policy.");
701 } 700 }
702 701
703 void ContentSecurityPolicy::reportUnsupportedDirective(const String& name) const 702 void ContentSecurityPolicy::reportUnsupportedDirective(const String& name)
704 { 703 {
705 DEFINE_STATIC_LOCAL(String, allow, ("allow")); 704 DEFINE_STATIC_LOCAL(String, allow, ("allow"));
706 DEFINE_STATIC_LOCAL(String, options, ("options")); 705 DEFINE_STATIC_LOCAL(String, options, ("options"));
707 DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri")); 706 DEFINE_STATIC_LOCAL(String, policyURI, ("policy-uri"));
708 DEFINE_STATIC_LOCAL(String, allowMessage, ("The 'allow' directive has been r eplaced with 'default-src'. Please use that directive instead, as 'allow' has no effect.")); 707 DEFINE_STATIC_LOCAL(String, allowMessage, ("The 'allow' directive has been r eplaced with 'default-src'. Please use that directive instead, as 'allow' has no effect."));
709 DEFINE_STATIC_LOCAL(String, optionsMessage, ("The 'options' directive has be en replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 's cript-src' and 'style-src' directives. Please use those directives instead, as ' options' has no effect.")); 708 DEFINE_STATIC_LOCAL(String, optionsMessage, ("The 'options' directive has be en replaced with 'unsafe-inline' and 'unsafe-eval' source expressions for the 's cript-src' and 'style-src' directives. Please use those directives instead, as ' options' has no effect."));
710 DEFINE_STATIC_LOCAL(String, policyURIMessage, ("The 'policy-uri' directive h as been removed from the specification. Please specify a complete policy via the Content-Security-Policy header.")); 709 DEFINE_STATIC_LOCAL(String, policyURIMessage, ("The 'policy-uri' directive h as been removed from the specification. Please specify a complete policy via the Content-Security-Policy header."));
711 710
712 String message = "Unrecognized Content-Security-Policy directive '" + name + "'.\n"; 711 String message = "Unrecognized Content-Security-Policy directive '" + name + "'.\n";
713 MessageLevel level = ErrorMessageLevel; 712 MessageLevel level = ErrorMessageLevel;
714 if (equalIgnoringCase(name, allow)) { 713 if (equalIgnoringCase(name, allow)) {
715 message = allowMessage; 714 message = allowMessage;
716 } else if (equalIgnoringCase(name, options)) { 715 } else if (equalIgnoringCase(name, options)) {
717 message = optionsMessage; 716 message = optionsMessage;
718 } else if (equalIgnoringCase(name, policyURI)) { 717 } else if (equalIgnoringCase(name, policyURI)) {
719 message = policyURIMessage; 718 message = policyURIMessage;
720 } else if (isDirectiveName(name)) { 719 } else if (isDirectiveName(name)) {
721 message = "The Content-Security-Policy directive '" + name + "' is imple mented behind a flag which is currently disabled.\n"; 720 message = "The Content-Security-Policy directive '" + name + "' is imple mented behind a flag which is currently disabled.\n";
722 level = InfoMessageLevel; 721 level = InfoMessageLevel;
723 } 722 }
724 723
725 logToConsole(message, level); 724 logToConsole(message, level);
726 } 725 }
727 726
728 void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& dire ctiveName, const String& sourceExpression) const 727 void ContentSecurityPolicy::reportDirectiveAsSourceExpression(const String& dire ctiveName, const String& sourceExpression)
729 { 728 {
730 String message = "The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?"; 729 String message = "The Content Security Policy directive '" + directiveName + "' contains '" + sourceExpression + "' as a source expression. Did you mean '" + directiveName + " ...; " + sourceExpression + "...' (note the semicolon)?";
731 logToConsole(message); 730 logToConsole(message);
732 } 731 }
733 732
734 void ContentSecurityPolicy::reportDuplicateDirective(const String& name) const 733 void ContentSecurityPolicy::reportDuplicateDirective(const String& name)
735 { 734 {
736 String message = "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n"; 735 String message = "Ignoring duplicate Content-Security-Policy directive '" + name + "'.\n";
737 logToConsole(message); 736 logToConsole(message);
738 } 737 }
739 738
740 void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType) c onst 739 void ContentSecurityPolicy::reportInvalidPluginTypes(const String& pluginType)
741 { 740 {
742 String message; 741 String message;
743 if (pluginType.isNull()) 742 if (pluginType.isNull())
744 message = "'plugin-types' Content Security Policy directive is empty; al l plugins will be blocked.\n"; 743 message = "'plugin-types' Content Security Policy directive is empty; al l plugins will be blocked.\n";
745 else 744 else
746 message = "Invalid plugin type in 'plugin-types' Content Security Policy directive: '" + pluginType + "'.\n"; 745 message = "Invalid plugin type in 'plugin-types' Content Security Policy directive: '" + pluginType + "'.\n";
747 logToConsole(message); 746 logToConsole(message);
748 } 747 }
749 748
750 void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags ) const 749 void ContentSecurityPolicy::reportInvalidSandboxFlags(const String& invalidFlags )
751 { 750 {
752 logToConsole("Error while parsing the 'sandbox' Content Security Policy dire ctive: " + invalidFlags); 751 logToConsole("Error while parsing the 'sandbox' Content Security Policy dire ctive: " + invalidFlags);
753 } 752 }
754 753
755 void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue ) const 754 void ContentSecurityPolicy::reportInvalidReflectedXSS(const String& invalidValue )
756 { 755 {
757 logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\"."); 756 logToConsole("The 'reflected-xss' Content Security Policy directive has the invalid value \"" + invalidValue + "\". Valid values are \"allow\", \"filter\", and \"block\".");
758 } 757 }
759 758
760 void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& d irectiveName, const String& value) const 759 void ContentSecurityPolicy::reportInvalidDirectiveValueCharacter(const String& d irectiveName, const String& value)
761 { 760 {
762 String message = "The value for Content Security Policy directive '" + direc tiveName + "' contains an invalid character: '" + value + "'. Non-whitespace cha racters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 398 6, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1."; 761 String message = "The value for Content Security Policy directive '" + direc tiveName + "' contains an invalid character: '" + value + "'. Non-whitespace cha racters outside ASCII 0x21-0x7E must be percent-encoded, as described in RFC 398 6, section 2.1: http://tools.ietf.org/html/rfc3986#section-2.1.";
763 logToConsole(message); 762 logToConsole(message);
764 } 763 }
765 764
766 void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveNa me, const String& value, const char invalidChar) const 765 void ContentSecurityPolicy::reportInvalidPathCharacter(const String& directiveNa me, const String& value, const char invalidChar)
767 { 766 {
768 ASSERT(invalidChar == '#' || invalidChar == '?'); 767 ASSERT(invalidChar == '#' || invalidChar == '?');
769 768
770 String ignoring = "The fragment identifier, including the '#', will be ignor ed."; 769 String ignoring = "The fragment identifier, including the '#', will be ignor ed.";
771 if (invalidChar == '?') 770 if (invalidChar == '?')
772 ignoring = "The query component, including the '?', will be ignored."; 771 ignoring = "The query component, including the '?', will be ignored.";
773 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring; 772 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains a source with an invalid path: '" + value + "'. " + ignoring;
774 logToConsole(message); 773 logToConsole(message);
775 } 774 }
776 775
777 void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiv eName, const String& source) const 776 void ContentSecurityPolicy::reportInvalidSourceExpression(const String& directiv eName, const String& source)
778 { 777 {
779 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ign ored."; 778 String message = "The source list for Content Security Policy directive '" + directiveName + "' contains an invalid source: '" + source + "'. It will be ign ored.";
780 if (equalIgnoringCase(source, "'none'")) 779 if (equalIgnoringCase(source, "'none'"))
781 message = message + " Note that 'none' has no effect unless it is the on ly expression in the source list."; 780 message = message + " Note that 'none' has no effect unless it is the on ly expression in the source list.";
782 logToConsole(message); 781 logToConsole(message);
783 } 782 }
784 783
785 void ContentSecurityPolicy::reportMissingReportURI(const String& policy) const 784 void ContentSecurityPolicy::reportMissingReportURI(const String& policy)
786 { 785 {
787 logToConsole("The Content Security Policy '" + policy + "' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no e ffect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header."); 786 logToConsole("The Content Security Policy '" + policy + "' was delivered in report-only mode, but does not specify a 'report-uri'; the policy will have no e ffect. Please either add a 'report-uri' directive, or deliver the policy via the 'Content-Security-Policy' header.");
788 } 787 }
789 788
790 void ContentSecurityPolicy::logToConsole(const String& message, MessageLevel lev el) const 789 void ContentSecurityPolicy::logToConsole(const String& message, MessageLevel lev el)
791 { 790 {
792 m_executionContext->addConsoleMessage(ConsoleMessage::create(SecurityMessage Source, level, message)); 791 logToConsole(ConsoleMessage::create(SecurityMessageSource, level, message));
792 }
793
794 void ContentSecurityPolicy::logToConsole(PassRefPtr<ConsoleMessage> consoleMessa ge)
795 {
796 if (m_executionContext)
797 m_executionContext->addConsoleMessage(consoleMessage);
798 else
799 m_consoleMessages.append(consoleMessage);
793 } 800 }
794 801
795 void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String & directiveText) const 802 void ContentSecurityPolicy::reportBlockedScriptExecutionToInspector(const String & directiveText) const
796 { 803 {
797 m_executionContext->reportBlockedScriptExecutionToInspector(directiveText); 804 m_executionContext->reportBlockedScriptExecutionToInspector(directiveText);
798 } 805 }
799 806
800 bool ContentSecurityPolicy::experimentalFeaturesEnabled() const 807 bool ContentSecurityPolicy::experimentalFeaturesEnabled() const
801 { 808 {
802 return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnab led(); 809 return RuntimeEnabledFeatures::experimentalContentSecurityPolicyFeaturesEnab led();
(...skipping 27 matching lines...) Expand all
830 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. 837 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report.
831 return !m_violationReportsSent.contains(report.impl()->hash()); 838 return !m_violationReportsSent.contains(report.impl()->hash());
832 } 839 }
833 840
834 void ContentSecurityPolicy::didSendViolationReport(const String& report) 841 void ContentSecurityPolicy::didSendViolationReport(const String& report)
835 { 842 {
836 m_violationReportsSent.add(report.impl()->hash()); 843 m_violationReportsSent.add(report.impl()->hash());
837 } 844 }
838 845
839 } // namespace blink 846 } // namespace blink
OLDNEW
« no previous file with comments | « Source/core/frame/csp/ContentSecurityPolicy.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698