Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/frame/csp/SourceListDirective.h" | 5 #include "core/frame/csp/SourceListDirective.h" |
| 6 | 6 |
| 7 #include "core/frame/csp/CSPSource.h" | 7 #include "core/frame/csp/CSPSource.h" |
| 8 #include "core/frame/csp/ContentSecurityPolicy.h" | 8 #include "core/frame/csp/ContentSecurityPolicy.h" |
| 9 #include "platform/network/ContentSecurityPolicyParsers.h" | 9 #include "platform/network/ContentSecurityPolicyParsers.h" |
| 10 #include "platform/weborigin/KURL.h" | 10 #include "platform/weborigin/KURL.h" |
| (...skipping 540 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 551 m_nonces.add(nonce); | 551 m_nonces.add(nonce); |
| 552 } | 552 } |
| 553 | 553 |
| 554 void SourceListDirective::addSourceHash( | 554 void SourceListDirective::addSourceHash( |
| 555 const ContentSecurityPolicyHashAlgorithm& algorithm, | 555 const ContentSecurityPolicyHashAlgorithm& algorithm, |
| 556 const DigestValue& hash) { | 556 const DigestValue& hash) { |
| 557 m_hashes.add(CSPHashValue(algorithm, hash)); | 557 m_hashes.add(CSPHashValue(algorithm, hash)); |
| 558 m_hashAlgorithmsUsed |= algorithm; | 558 m_hashAlgorithmsUsed |= algorithm; |
| 559 } | 559 } |
| 560 | 560 |
| 561 void SourceListDirective::addSourceToMap(HashMap<String, CSPSource*>& hashMap, | |
| 562 CSPSource* source) { | |
| 563 hashMap.add(source->getScheme(), source); | |
| 564 if (source->getScheme() == "http") | |
| 565 hashMap.add("https", source); | |
| 566 else if (source->getScheme() == "ws") | |
| 567 hashMap.add("wss", source); | |
| 568 } | |
| 569 | |
| 561 bool SourceListDirective::hasSourceMatchInList( | 570 bool SourceListDirective::hasSourceMatchInList( |
| 562 const KURL& url, | 571 const KURL& url, |
| 563 ResourceRequest::RedirectStatus redirectStatus) const { | 572 ResourceRequest::RedirectStatus redirectStatus) const { |
| 564 for (size_t i = 0; i < m_list.size(); ++i) { | 573 for (size_t i = 0; i < m_list.size(); ++i) { |
| 565 if (m_list[i]->matches(url, redirectStatus)) | 574 if (m_list[i]->matches(url, redirectStatus)) |
| 566 return true; | 575 return true; |
| 567 } | 576 } |
| 568 | 577 |
| 569 return false; | 578 return false; |
| 570 } | 579 } |
| 571 | 580 |
| 572 bool SourceListDirective::subsumes( | 581 bool SourceListDirective::subsumes( |
| 573 HeapVector<Member<SourceListDirective>> other) { | 582 HeapVector<Member<SourceListDirective>> other) { |
| 574 // TODO(amalika): Handle here special keywords. | 583 // TODO(amalika): Handle here special keywords. |
| 575 if (!m_list.size() || !other.size()) | 584 if (!m_list.size() || !other.size()) |
| 576 return !m_list.size(); | 585 return !m_list.size(); |
| 577 | 586 |
| 578 HeapVector<Member<CSPSource>> normalizedA = other[0]->m_list; | 587 HeapVector<Member<CSPSource>> normalizedA = other[0]->m_list; |
| 579 for (size_t i = 1; i < other.size(); i++) { | 588 for (size_t i = 1; i < other.size(); i++) { |
| 580 normalizedA = other[i]->getIntersectCSPSources(normalizedA); | 589 normalizedA = other[i]->getIntersectCSPSources(normalizedA); |
| 581 } | 590 } |
| 582 | 591 |
| 583 return CSPSource::firstSubsumesSecond(m_list, normalizedA); | 592 return CSPSource::firstSubsumesSecond(m_list, normalizedA); |
| 584 } | 593 } |
| 585 | 594 |
| 595 HashMap<String, CSPSource*> SourceListDirective::getIntersectSchemesOnly( | |
| 596 HeapVector<Member<CSPSource>> other) { | |
| 597 HashMap<String, CSPSource*> schemesA; | |
| 598 for (const auto& sourceA : m_list) { | |
| 599 if (sourceA->isSchemeOnly()) | |
| 600 addSourceToMap(schemesA, sourceA); | |
| 601 } | |
| 602 // Add schemes only sources if they are present in both `this` and `other`, | |
| 603 // allowing upgrading `http` to `https` and `ws` to `wss`. | |
| 604 HashMap<String, CSPSource*> intersect; | |
| 605 for (const auto& sourceB : other) { | |
| 606 if (sourceB->isSchemeOnly()) { | |
| 607 if (schemesA.contains(sourceB->getScheme())) | |
| 608 addSourceToMap(intersect, sourceB); | |
| 609 else if (sourceB->getScheme() == "http" && schemesA.contains("https")) | |
| 610 intersect.add("https", schemesA.get("https")); | |
| 611 else if (sourceB->getScheme() == "ws" && schemesA.contains("wss")) | |
| 612 intersect.add("wss", schemesA.get("wss")); | |
| 613 } | |
| 614 } | |
| 615 | |
| 616 return intersect; | |
| 617 } | |
| 618 | |
| 586 HeapVector<Member<CSPSource>> SourceListDirective::getIntersectCSPSources( | 619 HeapVector<Member<CSPSource>> SourceListDirective::getIntersectCSPSources( |
| 587 HeapVector<Member<CSPSource>> otherVector) { | 620 HeapVector<Member<CSPSource>> other) { |
| 621 HashMap<String, CSPSource*> schemesMap = getIntersectSchemesOnly(other); | |
| 588 HeapVector<Member<CSPSource>> normalized; | 622 HeapVector<Member<CSPSource>> normalized; |
| 589 for (const auto& aCspSource : m_list) { | 623 // Add all normalized scheme source expressions. |
| 590 Member<CSPSource> matchedCspSource(nullptr); | 624 for (auto it = schemesMap.begin(); it != schemesMap.end(); ++it) { |
|
Mike West
2016/11/24 14:00:54
`auto&`? Or do you need a copy? (Can this not be `
amalika
2016/11/24 14:50:33
It cannot be `const` since we are incrementing the
| |
| 591 for (const auto& bCspSource : otherVector) { | 625 // We do not add secure versions if insecure schemes are present. |
| 592 if ((matchedCspSource = bCspSource->intersect(aCspSource))) | 626 if ((it->key != "https" || !schemesMap.contains("http")) && |
| 627 (it->key != "wss" || !schemesMap.contains("ws"))) { | |
| 628 normalized.append(it->value); | |
| 629 } | |
| 630 } | |
| 631 | |
| 632 for (const auto& sourceA : m_list) { | |
| 633 if (schemesMap.contains(sourceA->getScheme())) | |
| 634 continue; | |
| 635 | |
| 636 CSPSource* match(nullptr); | |
| 637 for (const auto& sourceB : other) { | |
| 638 // No need to add a host source expression if it is subsumed by the | |
| 639 // matching scheme source expression. | |
| 640 if (schemesMap.contains(sourceB->getScheme())) | |
| 641 continue; | |
| 642 // If sourceA is scheme only but there was no intersection for it in the | |
| 643 // `other` list, we add all the sourceB with that scheme. | |
| 644 if (sourceA->isSchemeOnly()) { | |
| 645 if (CSPSource* localMatch = sourceB->intersect(sourceA)) | |
| 646 normalized.append(localMatch); | |
| 647 continue; | |
| 648 } | |
| 649 if (sourceB->subsumes(sourceA)) { | |
| 650 match = sourceA; | |
| 593 break; | 651 break; |
| 652 } | |
| 653 if (CSPSource* localMatch = sourceB->intersect(sourceA)) | |
| 654 match = localMatch; | |
| 594 } | 655 } |
| 595 if (matchedCspSource) | 656 if (match) |
| 596 normalized.append(matchedCspSource); | 657 normalized.append(match); |
| 597 } | 658 } |
| 598 return normalized; | 659 return normalized; |
| 599 } | 660 } |
| 600 | 661 |
| 601 DEFINE_TRACE(SourceListDirective) { | 662 DEFINE_TRACE(SourceListDirective) { |
| 602 visitor->trace(m_policy); | 663 visitor->trace(m_policy); |
| 603 visitor->trace(m_list); | 664 visitor->trace(m_list); |
| 604 CSPDirective::trace(visitor); | 665 CSPDirective::trace(visitor); |
| 605 } | 666 } |
| 606 | 667 |
| 607 } // namespace blink | 668 } // namespace blink |
| OLD | NEW |