OLD | NEW |
---|---|
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 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
129 } | 129 } |
130 | 130 |
131 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) | 131 static ReferrerPolicy mergeReferrerPolicies(ReferrerPolicy a, ReferrerPolicy b) |
132 { | 132 { |
133 if (a != b) | 133 if (a != b) |
134 return ReferrerPolicyNever; | 134 return ReferrerPolicyNever; |
135 return a; | 135 return a; |
136 } | 136 } |
137 | 137 |
138 ContentSecurityPolicy::ContentSecurityPolicy() | 138 ContentSecurityPolicy::ContentSecurityPolicy() |
139 : m_executionContext(0) | 139 : m_executionContext(nullptr) |
140 , m_overrideInlineStyleAllowed(false) | 140 , m_overrideInlineStyleAllowed(false) |
141 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) | 141 , m_scriptHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) |
142 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) | 142 , m_styleHashAlgorithmsUsed(ContentSecurityPolicyHashAlgorithmNone) |
143 , m_sandboxMask(0) | 143 , m_sandboxMask(0) |
144 , m_referrerPolicy(ReferrerPolicyDefault) | 144 , m_referrerPolicy(ReferrerPolicyDefault) |
145 { | 145 { |
146 } | 146 } |
147 | 147 |
148 void ContentSecurityPolicy::bindToExecutionContext(ExecutionContext* executionCo ntext) | 148 void ContentSecurityPolicy::bindToExecutionContext(ExecutionContext* executionCo ntext) |
149 { | 149 { |
(...skipping 29 matching lines...) Expand all Loading... | |
179 if (!m_disableEvalErrorMessage.isNull()) | 179 if (!m_disableEvalErrorMessage.isNull()) |
180 m_executionContext->disableEval(m_disableEvalErrorMessage); | 180 m_executionContext->disableEval(m_disableEvalErrorMessage); |
181 } | 181 } |
182 | 182 |
183 ContentSecurityPolicy::~ContentSecurityPolicy() | 183 ContentSecurityPolicy::~ContentSecurityPolicy() |
184 { | 184 { |
185 } | 185 } |
186 | 186 |
187 Document* ContentSecurityPolicy::document() const | 187 Document* ContentSecurityPolicy::document() const |
188 { | 188 { |
189 return m_executionContext->isDocument() ? toDocument(m_executionContext) : 0 ; | 189 return m_executionContext->isDocument() ? toDocument(m_executionContext) : n ullptr; |
190 } | 190 } |
191 | 191 |
192 void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other) | 192 void ContentSecurityPolicy::copyStateFrom(const ContentSecurityPolicy* other) |
193 { | 193 { |
194 ASSERT(m_policies.isEmpty()); | 194 ASSERT(m_policies.isEmpty()); |
195 for (const auto& cspDirective : other->m_policies) | 195 for (const auto& cspDirective : other->m_policies) |
196 addPolicyFromHeaderValue(cspDirective->header(), cspDirective->headerTyp e(), cspDirective->headerSource()); | 196 addPolicyFromHeaderValue(cspDirective->header(), cspDirective->headerTyp e(), cspDirective->headerSource()); |
197 } | 197 } |
198 | 198 |
199 void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyRespons eHeaders& headers) | 199 void ContentSecurityPolicy::didReceiveHeaders(const ContentSecurityPolicyRespons eHeaders& headers) |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
277 } | 277 } |
278 | 278 |
279 ContentSecurityPolicyHeaderType ContentSecurityPolicy::deprecatedHeaderType() co nst | 279 ContentSecurityPolicyHeaderType ContentSecurityPolicy::deprecatedHeaderType() co nst |
280 { | 280 { |
281 return m_policies.isEmpty() ? ContentSecurityPolicyHeaderTypeEnforce : m_pol icies[0]->headerType(); | 281 return m_policies.isEmpty() ? ContentSecurityPolicyHeaderTypeEnforce : m_pol icies[0]->headerType(); |
282 } | 282 } |
283 | 283 |
284 template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatu s) const> | 284 template<bool (CSPDirectiveList::*allowed)(ContentSecurityPolicy::ReportingStatu s) const> |
285 bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolic y::ReportingStatus reportingStatus) | 285 bool isAllowedByAll(const CSPDirectiveListVector& policies, ContentSecurityPolic y::ReportingStatus reportingStatus) |
286 { | 286 { |
287 for (size_t i = 0; i < policies.size(); ++i) { | 287 for (const auto& cspDirective : policies) { |
288 if (!(policies[i].get()->*allowed)(reportingStatus)) | 288 if (!(cspDirective.get()->*allowed)(reportingStatus)) |
289 return false; | 289 return false; |
290 } | 290 } |
291 return true; | 291 return true; |
292 } | 292 } |
293 | 293 |
294 template<bool (CSPDirectiveList::*allowed)(ScriptState* scriptState, ContentSecu rityPolicy::ReportingStatus) const> | 294 template<bool (CSPDirectiveList::*allowed)(ScriptState* scriptState, ContentSecu rityPolicy::ReportingStatus) const> |
295 bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, ScriptState * scriptState, ContentSecurityPolicy::ReportingStatus reportingStatus) | 295 bool isAllowedByAllWithState(const CSPDirectiveListVector& policies, ScriptState * scriptState, ContentSecurityPolicy::ReportingStatus reportingStatus) |
296 { | 296 { |
297 for (size_t i = 0; i < policies.size(); ++i) { | 297 for (const auto& cspDirective : policies) { |
298 if (!(policies[i].get()->*allowed)(scriptState, reportingStatus)) | 298 if (!(cspDirective.get()->*allowed)(scriptState, reportingStatus)) |
299 return false; | 299 return false; |
300 } | 300 } |
301 return true; | 301 return true; |
302 } | 302 } |
303 | 303 |
304 template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumb er&, ContentSecurityPolicy::ReportingStatus) const> | 304 template<bool (CSPDirectiveList::*allowed)(const String&, const WTF::OrdinalNumb er&, ContentSecurityPolicy::ReportingStatus) const> |
305 bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const Str ing& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::R eportingStatus reportingStatus) | 305 bool isAllowedByAllWithContext(const CSPDirectiveListVector& policies, const Str ing& contextURL, const WTF::OrdinalNumber& contextLine, ContentSecurityPolicy::R eportingStatus reportingStatus) |
306 { | 306 { |
307 for (size_t i = 0; i < policies.size(); ++i) { | 307 for (const auto& cspDirective : policies) { |
308 if (!(policies[i].get()->*allowed)(contextURL, contextLine, reportingSta tus)) | 308 if (!(cspDirective.get()->*allowed)(contextURL, contextLine, reportingSt atus)) |
309 return false; | 309 return false; |
310 } | 310 } |
311 return true; | 311 return true; |
312 } | 312 } |
313 | 313 |
314 template<bool (CSPDirectiveList::*allowed)(const String&) const> | 314 template<bool (CSPDirectiveList::*allowed)(const String&) const> |
315 bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const Strin g& nonce) | 315 bool isAllowedByAllWithNonce(const CSPDirectiveListVector& policies, const Strin g& nonce) |
316 { | 316 { |
317 for (size_t i = 0; i < policies.size(); ++i) { | 317 for (const auto& cspDirective : policies) { |
318 if (!(policies[i].get()->*allowed)(nonce)) | 318 if (!(cspDirective.get()->*allowed)(nonce)) |
319 return false; | 319 return false; |
320 } | 320 } |
321 return true; | 321 return true; |
322 } | 322 } |
323 | 323 |
324 template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const> | 324 template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const> |
325 bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHas hValue& hashValue) | 325 bool isAllowedByAllWithHash(const CSPDirectiveListVector& policies, const CSPHas hValue& hashValue) |
326 { | 326 { |
327 for (size_t i = 0; i < policies.size(); ++i) { | 327 for (const auto& cspDirective : policies) { |
328 if (!(policies[i].get()->*allowed)(hashValue)) | 328 if (!(cspDirective.get()->*allowed)(hashValue)) |
329 return false; | 329 return false; |
330 } | 330 } |
331 return true; | 331 return true; |
332 } | 332 } |
333 | 333 |
334 template<bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPoli cy::ReportingStatus) const> | 334 template<bool (CSPDirectiveList::*allowFromURL)(const KURL&, ContentSecurityPoli cy::ReportingStatus) const> |
335 bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u rl, ContentSecurityPolicy::ReportingStatus reportingStatus) | 335 bool isAllowedByAllWithURL(const CSPDirectiveListVector& policies, const KURL& u rl, ContentSecurityPolicy::ReportingStatus reportingStatus) |
336 { | 336 { |
337 if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol())) | 337 if (SchemeRegistry::schemeShouldBypassContentSecurityPolicy(url.protocol())) |
338 return true; | 338 return true; |
339 | 339 |
340 for (size_t i = 0; i < policies.size(); ++i) { | 340 for (const auto& cspDirective : policies) { |
341 if (!(policies[i].get()->*allowFromURL)(url, reportingStatus)) | 341 if (!(cspDirective.get()->*allowFromURL)(url, reportingStatus)) |
342 return false; | 342 return false; |
343 } | 343 } |
344 return true; | 344 return true; |
345 } | 345 } |
346 | 346 |
347 template<bool (CSPDirectiveList::*allowed)(LocalFrame*, const KURL&, ContentSecu rityPolicy::ReportingStatus) const> | 347 template<bool (CSPDirectiveList::*allowed)(LocalFrame*, const KURL&, ContentSecu rityPolicy::ReportingStatus) const> |
348 bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame* frame, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) | 348 bool isAllowedByAllWithFrame(const CSPDirectiveListVector& policies, LocalFrame* frame, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingStatus) |
349 { | 349 { |
350 for (size_t i = 0; i < policies.size(); ++i) { | 350 for (const auto& cspDirective : policies) { |
351 if (!(policies[i].get()->*allowed)(frame, url, reportingStatus)) | 351 if (!(cspDirective.get()->*allowed)(frame, url, reportingStatus)) |
352 return false; | 352 return false; |
353 } | 353 } |
354 return true; | 354 return true; |
355 } | 355 } |
356 | 356 |
357 template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const> | 357 template<bool (CSPDirectiveList::*allowed)(const CSPHashValue&) const> |
358 bool checkDigest(const String& source, uint8_t hashAlgorithmsUsed, const CSPDire ctiveListVector& policies) | 358 bool checkDigest(const String& source, uint8_t hashAlgorithmsUsed, const CSPDire ctiveListVector& policies) |
359 { | 359 { |
360 // Any additions or subtractions from this struct should also modify the | 360 // Any additions or subtractions from this struct should also modify the |
361 // respective entries in the kSupportedPrefixes array in | 361 // respective entries in the kSupportedPrefixes array in |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
412 return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineStyle>(m_poli cies, contextURL, contextLine, reportingStatus); | 412 return isAllowedByAllWithContext<&CSPDirectiveList::allowInlineStyle>(m_poli cies, contextURL, contextLine, reportingStatus); |
413 } | 413 } |
414 | 414 |
415 bool ContentSecurityPolicy::allowEval(ScriptState* scriptState, ContentSecurityP olicy::ReportingStatus reportingStatus) const | 415 bool ContentSecurityPolicy::allowEval(ScriptState* scriptState, ContentSecurityP olicy::ReportingStatus reportingStatus) const |
416 { | 416 { |
417 return isAllowedByAllWithState<&CSPDirectiveList::allowEval>(m_policies, scr iptState, reportingStatus); | 417 return isAllowedByAllWithState<&CSPDirectiveList::allowEval>(m_policies, scr iptState, reportingStatus); |
418 } | 418 } |
419 | 419 |
420 String ContentSecurityPolicy::evalDisabledErrorMessage() const | 420 String ContentSecurityPolicy::evalDisabledErrorMessage() const |
421 { | 421 { |
422 for (size_t i = 0; i < m_policies.size(); ++i) { | 422 for (const auto& cspDirective : m_policies) { |
423 if (!m_policies[i]->allowEval(0, SuppressReport)) | 423 if (!cspDirective->allowEval(0, SuppressReport)) |
424 return m_policies[i]->evalDisabledErrorMessage(); | 424 return cspDirective->evalDisabledErrorMessage(); |
425 } | 425 } |
426 return String(); | 426 return String(); |
427 } | 427 } |
428 | 428 |
429 bool ContentSecurityPolicy::allowPluginType(const String& type, const String& ty peAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingSt atus) const | 429 bool ContentSecurityPolicy::allowPluginType(const String& type, const String& ty peAttribute, const KURL& url, ContentSecurityPolicy::ReportingStatus reportingSt atus) const |
430 { | 430 { |
431 for (size_t i = 0; i < m_policies.size(); ++i) { | 431 for (const auto& cspDirective : m_policies) { |
432 if (!m_policies[i]->allowPluginType(type, typeAttribute, url, reportingS tatus)) | 432 if (!cspDirective->allowPluginType(type, typeAttribute, url, reportingSt atus)) |
433 return false; | 433 return false; |
434 } | 434 } |
435 return true; | 435 return true; |
436 } | 436 } |
437 | 437 |
438 bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url, ContentSecuri tyPolicy::ReportingStatus reportingStatus) const | 438 bool ContentSecurityPolicy::allowScriptFromSource(const KURL& url, ContentSecuri tyPolicy::ReportingStatus reportingStatus) const |
439 { | 439 { |
440 return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_pol icies, url, reportingStatus); | 440 return isAllowedByAllWithURL<&CSPDirectiveList::allowScriptFromSource>(m_pol icies, url, reportingStatus); |
441 } | 441 } |
442 | 442 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
543 } | 543 } |
544 | 544 |
545 bool ContentSecurityPolicy::isActive() const | 545 bool ContentSecurityPolicy::isActive() const |
546 { | 546 { |
547 return !m_policies.isEmpty(); | 547 return !m_policies.isEmpty(); |
548 } | 548 } |
549 | 549 |
550 ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const | 550 ReflectedXSSDisposition ContentSecurityPolicy::reflectedXSSDisposition() const |
551 { | 551 { |
552 ReflectedXSSDisposition disposition = ReflectedXSSUnset; | 552 ReflectedXSSDisposition disposition = ReflectedXSSUnset; |
553 for (size_t i = 0; i < m_policies.size(); ++i) { | 553 for (const auto& cspDirective : m_policies) { |
554 if (m_policies[i]->reflectedXSSDisposition() > disposition) | 554 if (cspDirective->reflectedXSSDisposition() > disposition) |
555 disposition = std::max(disposition, m_policies[i]->reflectedXSSDispo sition()); | 555 disposition = std::max(disposition, cspDirective->reflectedXSSDispos ition()); |
556 } | 556 } |
557 return disposition; | 557 return disposition; |
558 } | 558 } |
559 | 559 |
560 ReferrerPolicy ContentSecurityPolicy::referrerPolicy() const | 560 ReferrerPolicy ContentSecurityPolicy::referrerPolicy() const |
561 { | 561 { |
562 ReferrerPolicy policy = ReferrerPolicyDefault; | 562 ReferrerPolicy policy = ReferrerPolicyDefault; |
563 bool first = true; | 563 bool first = true; |
564 for (size_t i = 0; i < m_policies.size(); ++i) { | 564 for (const auto& cspDirective : m_policies) { |
565 if (m_policies[i]->didSetReferrerPolicy()) { | 565 if (cspDirective->didSetReferrerPolicy()) { |
566 if (first) | 566 if (first) |
567 policy = m_policies[i]->referrerPolicy(); | 567 policy = cspDirective->referrerPolicy(); |
568 else | 568 else |
569 policy = mergeReferrerPolicies(policy, m_policies[i]->referrerPo licy()); | 569 policy = mergeReferrerPolicies(policy, cspDirective->referrerPol icy()); |
570 } | 570 } |
571 } | 571 } |
572 return policy; | 572 return policy; |
573 } | 573 } |
574 | 574 |
575 bool ContentSecurityPolicy::didSetReferrerPolicy() const | 575 bool ContentSecurityPolicy::didSetReferrerPolicy() const |
576 { | 576 { |
577 for (size_t i = 0; i < m_policies.size(); ++i) { | 577 for (const auto& cspDirective : m_policies) { |
Mike West
2014/10/16 19:35:07
Nit: Here, and pretty much everywhere else, s/cspD
| |
578 if (m_policies[i]->didSetReferrerPolicy()) | 578 if (cspDirective->didSetReferrerPolicy()) |
579 return true; | 579 return true; |
580 } | 580 } |
581 return false; | 581 return false; |
582 } | 582 } |
583 | 583 |
584 SecurityOrigin* ContentSecurityPolicy::securityOrigin() const | 584 SecurityOrigin* ContentSecurityPolicy::securityOrigin() const |
585 { | 585 { |
586 return m_executionContext->securityContext().securityOrigin(); | 586 return m_executionContext->securityContext().securityOrigin(); |
587 } | 587 } |
588 | 588 |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
695 | 695 |
696 RefPtr<JSONObject> reportObject = JSONObject::create(); | 696 RefPtr<JSONObject> reportObject = JSONObject::create(); |
697 reportObject->setObject("csp-report", cspReport.release()); | 697 reportObject->setObject("csp-report", cspReport.release()); |
698 String stringifiedReport = reportObject->toJSONString(); | 698 String stringifiedReport = reportObject->toJSONString(); |
699 | 699 |
700 if (!shouldSendViolationReport(stringifiedReport)) | 700 if (!shouldSendViolationReport(stringifiedReport)) |
701 return; | 701 return; |
702 | 702 |
703 RefPtr<FormData> report = FormData::create(stringifiedReport.utf8()); | 703 RefPtr<FormData> report = FormData::create(stringifiedReport.utf8()); |
704 | 704 |
705 for (size_t i = 0; i < reportEndpoints.size(); ++i) { | 705 for (const String& endpoint : reportEndpoints) { |
706 // If we have a context frame we're dealing with 'frame-ancestors' and w e don't have our | 706 // If we have a context frame we're dealing with 'frame-ancestors' and w e don't have our |
707 // own execution context. Use the frame's document to complete the endpo int URL, overriding | 707 // own execution context. Use the frame's document to complete the endpo int URL, overriding |
708 // its URL with the blocked document's URL. | 708 // its URL with the blocked document's URL. |
709 ASSERT(!contextFrame || !m_executionContext); | 709 ASSERT(!contextFrame || !m_executionContext); |
710 ASSERT(!contextFrame || equalIgnoringCase(effectiveDirective, FrameAnces tors)); | 710 ASSERT(!contextFrame || equalIgnoringCase(effectiveDirective, FrameAnces tors)); |
711 KURL endpoint = contextFrame ? frame->document()->completeURLWithOverrid e(reportEndpoints[i], blockedURL) : completeURL(reportEndpoints[i]); | 711 // FIXME: What is the below line used for? |
712 PingLoader::sendViolationReport(frame, completeURL(reportEndpoints[i]), report, PingLoader::ContentSecurityPolicyViolationReport); | 712 KURL url = contextFrame ? frame->document()->completeURLWithOverride(end point, blockedURL) : completeURL(endpoint); |
713 PingLoader::sendViolationReport(frame, completeURL(endpoint), report, Pi ngLoader::ContentSecurityPolicyViolationReport); | |
Mike West
2014/10/16 19:35:07
Oops. Please s/completeURL(endpoint)/url/g in this
| |
713 } | 714 } |
714 | 715 |
715 didSendViolationReport(stringifiedReport); | 716 didSendViolationReport(stringifiedReport); |
716 } | 717 } |
717 | 718 |
718 void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) | 719 void ContentSecurityPolicy::reportInvalidReferrer(const String& invalidValue) |
719 { | 720 { |
720 logToConsole("The 'referrer' Content Security Policy directive has the inval id value \"" + invalidValue + "\". Valid values are \"no-referrer\", \"no-referr er-when-downgrade\", \"origin\", and \"unsafe-url\". Note that \"origin-when-cro ss-origin\" is not yet supported."); | 721 logToConsole("The 'referrer' Content Security Policy directive has the inval id value \"" + invalidValue + "\". Valid values are \"no-referrer\", \"no-referr er-when-downgrade\", \"origin\", and \"unsafe-url\". Note that \"origin-when-cro ss-origin\" is not yet supported."); |
721 } | 722 } |
722 | 723 |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
874 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. | 875 // Collisions have no security impact, so we can save space by storing only the string's hash rather than the whole report. |
875 return !m_violationReportsSent.contains(report.impl()->hash()); | 876 return !m_violationReportsSent.contains(report.impl()->hash()); |
876 } | 877 } |
877 | 878 |
878 void ContentSecurityPolicy::didSendViolationReport(const String& report) | 879 void ContentSecurityPolicy::didSendViolationReport(const String& report) |
879 { | 880 { |
880 m_violationReportsSent.add(report.impl()->hash()); | 881 m_violationReportsSent.add(report.impl()->hash()); |
881 } | 882 } |
882 | 883 |
883 } // namespace blink | 884 } // namespace blink |
OLD | NEW |