| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 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 are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 573 } else { | 573 } else { |
| 574 message = "Unsafe attempt to load URL " + url.elidedString() + | 574 message = "Unsafe attempt to load URL " + url.elidedString() + |
| 575 " from frame with URL " + m_document->url().elidedString() + | 575 " from frame with URL " + m_document->url().elidedString() + |
| 576 ". Domains, protocols and ports must match.\n"; | 576 ". Domains, protocols and ports must match.\n"; |
| 577 } | 577 } |
| 578 | 578 |
| 579 frame()->document()->addConsoleMessage(ConsoleMessage::create( | 579 frame()->document()->addConsoleMessage(ConsoleMessage::create( |
| 580 SecurityMessageSource, ErrorMessageLevel, message)); | 580 SecurityMessageSource, ErrorMessageLevel, message)); |
| 581 } | 581 } |
| 582 | 582 |
| 583 bool FrameFetchContext::canRequest( | 583 ResourceRequestBlockedReason FrameFetchContext::canRequest( |
| 584 Resource::Type type, | 584 Resource::Type type, |
| 585 const ResourceRequest& resourceRequest, | 585 const ResourceRequest& resourceRequest, |
| 586 const KURL& url, | 586 const KURL& url, |
| 587 const ResourceLoaderOptions& options, | 587 const ResourceLoaderOptions& options, |
| 588 bool forPreload, | 588 bool forPreload, |
| 589 FetchRequest::OriginRestriction originRestriction) const { | 589 FetchRequest::OriginRestriction originRestriction) const { |
| 590 ResourceRequestBlockedReason reason = | 590 ResourceRequestBlockedReason blockedReason = |
| 591 canRequestInternal(type, resourceRequest, url, options, forPreload, | 591 canRequestInternal(type, resourceRequest, url, options, forPreload, |
| 592 originRestriction, resourceRequest.redirectStatus()); | 592 originRestriction, resourceRequest.redirectStatus()); |
| 593 if (reason != ResourceRequestBlockedReasonNone) { | 593 if (blockedReason != ResourceRequestBlockedReason::None && !forPreload) { |
| 594 if (!forPreload) { | 594 InspectorInstrumentation::didBlockRequest( |
| 595 InspectorInstrumentation::didBlockRequest(frame(), resourceRequest, | 595 frame(), resourceRequest, masterDocumentLoader(), options.initiatorInfo, |
| 596 masterDocumentLoader(), | 596 blockedReason); |
| 597 options.initiatorInfo, reason); | |
| 598 } | |
| 599 return false; | |
| 600 } | 597 } |
| 601 return true; | 598 return blockedReason; |
| 602 } | 599 } |
| 603 | 600 |
| 604 bool FrameFetchContext::allowResponse( | 601 ResourceRequestBlockedReason FrameFetchContext::allowResponse( |
| 605 Resource::Type type, | 602 Resource::Type type, |
| 606 const ResourceRequest& resourceRequest, | 603 const ResourceRequest& resourceRequest, |
| 607 const KURL& url, | 604 const KURL& url, |
| 608 const ResourceLoaderOptions& options) const { | 605 const ResourceLoaderOptions& options) const { |
| 609 ResourceRequestBlockedReason reason = | 606 ResourceRequestBlockedReason blockedReason = |
| 610 canRequestInternal(type, resourceRequest, url, options, false, | 607 canRequestInternal(type, resourceRequest, url, options, false, |
| 611 FetchRequest::UseDefaultOriginRestrictionForType, | 608 FetchRequest::UseDefaultOriginRestrictionForType, |
| 612 RedirectStatus::FollowedRedirect); | 609 RedirectStatus::FollowedRedirect); |
| 613 if (reason != ResourceRequestBlockedReasonNone) { | 610 if (blockedReason != ResourceRequestBlockedReason::None) { |
| 614 InspectorInstrumentation::didBlockRequest(frame(), resourceRequest, | 611 InspectorInstrumentation::didBlockRequest( |
| 615 masterDocumentLoader(), | 612 frame(), resourceRequest, masterDocumentLoader(), options.initiatorInfo, |
| 616 options.initiatorInfo, reason); | 613 blockedReason); |
| 617 return false; | |
| 618 } | 614 } |
| 619 return true; | 615 return blockedReason; |
| 620 } | 616 } |
| 621 | 617 |
| 622 ResourceRequestBlockedReason FrameFetchContext::canRequestInternal( | 618 ResourceRequestBlockedReason FrameFetchContext::canRequestInternal( |
| 623 Resource::Type type, | 619 Resource::Type type, |
| 624 const ResourceRequest& resourceRequest, | 620 const ResourceRequest& resourceRequest, |
| 625 const KURL& url, | 621 const KURL& url, |
| 626 const ResourceLoaderOptions& options, | 622 const ResourceLoaderOptions& options, |
| 627 bool forPreload, | 623 bool forPreload, |
| 628 FetchRequest::OriginRestriction originRestriction, | 624 FetchRequest::OriginRestriction originRestriction, |
| 629 ResourceRequest::RedirectStatus redirectStatus) const { | 625 ResourceRequest::RedirectStatus redirectStatus) const { |
| 630 if (InspectorInstrumentation::shouldBlockRequest(frame(), resourceRequest)) | 626 if (InspectorInstrumentation::shouldBlockRequest(frame(), resourceRequest)) |
| 631 return ResourceRequestBlockedReasonInspector; | 627 return ResourceRequestBlockedReason::Inspector; |
| 632 | 628 |
| 633 SecurityOrigin* securityOrigin = options.securityOrigin.get(); | 629 SecurityOrigin* securityOrigin = options.securityOrigin.get(); |
| 634 if (!securityOrigin && m_document) | 630 if (!securityOrigin && m_document) |
| 635 securityOrigin = m_document->getSecurityOrigin(); | 631 securityOrigin = m_document->getSecurityOrigin(); |
| 636 | 632 |
| 637 if (originRestriction != FetchRequest::NoOriginRestriction && | 633 if (originRestriction != FetchRequest::NoOriginRestriction && |
| 638 securityOrigin && !securityOrigin->canDisplay(url)) { | 634 securityOrigin && !securityOrigin->canDisplay(url)) { |
| 639 if (!forPreload) | 635 if (!forPreload) |
| 640 FrameLoader::reportLocalLoadFailed(frame(), url.elidedString()); | 636 FrameLoader::reportLocalLoadFailed(frame(), url.elidedString()); |
| 641 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::requestResource URL was not " | 637 RESOURCE_LOADING_DVLOG(1) << "ResourceFetcher::requestResource URL was not " |
| 642 "allowed by SecurityOrigin::canDisplay"; | 638 "allowed by SecurityOrigin::canDisplay"; |
| 643 return ResourceRequestBlockedReasonOther; | 639 return ResourceRequestBlockedReason::Other; |
| 644 } | 640 } |
| 645 | 641 |
| 646 // Some types of resources can be loaded only from the same origin. Other | 642 // Some types of resources can be loaded only from the same origin. Other |
| 647 // types of resources, like Images, Scripts, and CSS, can be loaded from | 643 // types of resources, like Images, Scripts, and CSS, can be loaded from |
| 648 // any URL. | 644 // any URL. |
| 649 switch (type) { | 645 switch (type) { |
| 650 case Resource::MainResource: | 646 case Resource::MainResource: |
| 651 case Resource::Image: | 647 case Resource::Image: |
| 652 case Resource::CSSStyleSheet: | 648 case Resource::CSSStyleSheet: |
| 653 case Resource::Script: | 649 case Resource::Script: |
| 654 case Resource::Font: | 650 case Resource::Font: |
| 655 case Resource::Raw: | 651 case Resource::Raw: |
| 656 case Resource::LinkPrefetch: | 652 case Resource::LinkPrefetch: |
| 657 case Resource::TextTrack: | 653 case Resource::TextTrack: |
| 658 case Resource::ImportResource: | 654 case Resource::ImportResource: |
| 659 case Resource::Media: | 655 case Resource::Media: |
| 660 case Resource::Manifest: | 656 case Resource::Manifest: |
| 661 // By default these types of resources can be loaded from any origin. | 657 // By default these types of resources can be loaded from any origin. |
| 662 // FIXME: Are we sure about Resource::Font? | 658 // FIXME: Are we sure about Resource::Font? |
| 663 if (originRestriction == FetchRequest::RestrictToSameOrigin && | 659 if (originRestriction == FetchRequest::RestrictToSameOrigin && |
| 664 !securityOrigin->canRequest(url)) { | 660 !securityOrigin->canRequest(url)) { |
| 665 printAccessDeniedMessage(url); | 661 printAccessDeniedMessage(url); |
| 666 return ResourceRequestBlockedReasonOrigin; | 662 return ResourceRequestBlockedReason::Origin; |
| 667 } | 663 } |
| 668 break; | 664 break; |
| 669 case Resource::XSLStyleSheet: | 665 case Resource::XSLStyleSheet: |
| 670 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); | 666 DCHECK(RuntimeEnabledFeatures::xsltEnabled()); |
| 671 case Resource::SVGDocument: | 667 case Resource::SVGDocument: |
| 672 if (!securityOrigin->canRequest(url)) { | 668 if (!securityOrigin->canRequest(url)) { |
| 673 printAccessDeniedMessage(url); | 669 printAccessDeniedMessage(url); |
| 674 return ResourceRequestBlockedReasonOrigin; | 670 return ResourceRequestBlockedReason::Origin; |
| 675 } | 671 } |
| 676 break; | 672 break; |
| 677 } | 673 } |
| 678 | 674 |
| 679 // FIXME: Convert this to check the isolated world's Content Security Policy | 675 // FIXME: Convert this to check the isolated world's Content Security Policy |
| 680 // once webkit.org/b/104520 is solved. | 676 // once webkit.org/b/104520 is solved. |
| 681 bool shouldBypassMainWorldCSP = | 677 bool shouldBypassMainWorldCSP = |
| 682 frame()->script().shouldBypassMainWorldCSP() || | 678 frame()->script().shouldBypassMainWorldCSP() || |
| 683 options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy; | 679 options.contentSecurityPolicyOption == DoNotCheckContentSecurityPolicy; |
| 684 | 680 |
| 685 // Don't send CSP messages for preloads, we might never actually display those | 681 // Don't send CSP messages for preloads, we might never actually display those |
| 686 // items. | 682 // items. |
| 687 ContentSecurityPolicy::ReportingStatus cspReporting = | 683 ContentSecurityPolicy::ReportingStatus cspReporting = |
| 688 forPreload ? ContentSecurityPolicy::SuppressReport | 684 forPreload ? ContentSecurityPolicy::SuppressReport |
| 689 : ContentSecurityPolicy::SendReport; | 685 : ContentSecurityPolicy::SendReport; |
| 690 | 686 |
| 691 if (m_document) { | 687 if (m_document) { |
| 692 DCHECK(m_document->contentSecurityPolicy()); | 688 DCHECK(m_document->contentSecurityPolicy()); |
| 693 if (!shouldBypassMainWorldCSP && | 689 if (!shouldBypassMainWorldCSP && |
| 694 !m_document->contentSecurityPolicy()->allowRequest( | 690 !m_document->contentSecurityPolicy()->allowRequest( |
| 695 resourceRequest.requestContext(), url, | 691 resourceRequest.requestContext(), url, |
| 696 options.contentSecurityPolicyNonce, options.integrityMetadata, | 692 options.contentSecurityPolicyNonce, options.integrityMetadata, |
| 697 options.parserDisposition, redirectStatus, cspReporting)) | 693 options.parserDisposition, redirectStatus, cspReporting)) |
| 698 return ResourceRequestBlockedReasonCSP; | 694 return ResourceRequestBlockedReason::CSP; |
| 699 } | 695 } |
| 700 | 696 |
| 701 if (type == Resource::Script || type == Resource::ImportResource) { | 697 if (type == Resource::Script || type == Resource::ImportResource) { |
| 702 DCHECK(frame()); | 698 DCHECK(frame()); |
| 703 if (!frame()->loader().client()->allowScriptFromSource( | 699 if (!frame()->loader().client()->allowScriptFromSource( |
| 704 !frame()->settings() || frame()->settings()->scriptEnabled(), | 700 !frame()->settings() || frame()->settings()->scriptEnabled(), |
| 705 url)) { | 701 url)) { |
| 706 frame()->loader().client()->didNotAllowScript(); | 702 frame()->loader().client()->didNotAllowScript(); |
| 707 // TODO(estark): Use a different ResourceRequestBlockedReason here, since | 703 // TODO(estark): Use a different ResourceRequestBlockedReason here, since |
| 708 // this check has nothing to do with CSP. https://crbug.com/600795 | 704 // this check has nothing to do with CSP. https://crbug.com/600795 |
| 709 return ResourceRequestBlockedReasonCSP; | 705 return ResourceRequestBlockedReason::CSP; |
| 710 } | 706 } |
| 711 } else if (type == Resource::Media || type == Resource::TextTrack) { | 707 } else if (type == Resource::Media || type == Resource::TextTrack) { |
| 712 DCHECK(frame()); | 708 DCHECK(frame()); |
| 713 if (!frame()->loader().client()->allowMedia(url)) | 709 if (!frame()->loader().client()->allowMedia(url)) |
| 714 return ResourceRequestBlockedReasonOther; | 710 return ResourceRequestBlockedReason::Other; |
| 715 } | 711 } |
| 716 | 712 |
| 717 // SVG Images have unique security rules that prevent all subresource requests | 713 // SVG Images have unique security rules that prevent all subresource requests |
| 718 // except for data urls. | 714 // except for data urls. |
| 719 if (type != Resource::MainResource && | 715 if (type != Resource::MainResource && |
| 720 frame()->chromeClient().isSVGImageChromeClient() && !url.protocolIsData()) | 716 frame()->chromeClient().isSVGImageChromeClient() && !url.protocolIsData()) |
| 721 return ResourceRequestBlockedReasonOrigin; | 717 return ResourceRequestBlockedReason::Origin; |
| 722 | 718 |
| 723 // Measure the number of legacy URL schemes ('ftp://') and the number of | 719 // Measure the number of legacy URL schemes ('ftp://') and the number of |
| 724 // embedded-credential ('http://user:password@...') resources embedded as | 720 // embedded-credential ('http://user:password@...') resources embedded as |
| 725 // subresources. in the hopes that we can block them at some point in the | 721 // subresources. in the hopes that we can block them at some point in the |
| 726 // future. | 722 // future. |
| 727 if (resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel) { | 723 if (resourceRequest.frameType() != WebURLRequest::FrameTypeTopLevel) { |
| 728 DCHECK(frame()->document()); | 724 DCHECK(frame()->document()); |
| 729 if (SchemeRegistry::shouldTreatURLSchemeAsLegacy(url.protocol()) && | 725 if (SchemeRegistry::shouldTreatURLSchemeAsLegacy(url.protocol()) && |
| 730 !SchemeRegistry::shouldTreatURLSchemeAsLegacy( | 726 !SchemeRegistry::shouldTreatURLSchemeAsLegacy( |
| 731 frame()->document()->getSecurityOrigin()->protocol())) { | 727 frame()->document()->getSecurityOrigin()->protocol())) { |
| 732 UseCounter::count(frame()->document(), | 728 UseCounter::count(frame()->document(), |
| 733 UseCounter::LegacyProtocolEmbeddedAsSubresource); | 729 UseCounter::LegacyProtocolEmbeddedAsSubresource); |
| 734 } | 730 } |
| 735 if (!url.user().isEmpty() || !url.pass().isEmpty()) { | 731 if (!url.user().isEmpty() || !url.pass().isEmpty()) { |
| 736 UseCounter::count( | 732 UseCounter::count( |
| 737 frame()->document(), | 733 frame()->document(), |
| 738 UseCounter::RequestedSubresourceWithEmbeddedCredentials); | 734 UseCounter::RequestedSubresourceWithEmbeddedCredentials); |
| 739 } | 735 } |
| 740 } | 736 } |
| 741 | 737 |
| 742 // Check for mixed content. We do this second-to-last so that when folks block | 738 // Check for mixed content. We do this second-to-last so that when folks block |
| 743 // mixed content with a CSP policy, they don't get a warning. They'll still | 739 // mixed content with a CSP policy, they don't get a warning. They'll still |
| 744 // get a warning in the console about CSP blocking the load. | 740 // get a warning in the console about CSP blocking the load. |
| 745 MixedContentChecker::ReportingStatus mixedContentReporting = | 741 MixedContentChecker::ReportingStatus mixedContentReporting = |
| 746 forPreload ? MixedContentChecker::SuppressReport | 742 forPreload ? MixedContentChecker::SuppressReport |
| 747 : MixedContentChecker::SendReport; | 743 : MixedContentChecker::SendReport; |
| 748 if (MixedContentChecker::shouldBlockFetch(frame(), resourceRequest, url, | 744 if (MixedContentChecker::shouldBlockFetch(frame(), resourceRequest, url, |
| 749 mixedContentReporting)) | 745 mixedContentReporting)) |
| 750 return ResourceRequestBlockedReasonMixedContent; | 746 return ResourceRequestBlockedReason::MixedContent; |
| 751 | 747 |
| 752 // Let the client have the final say into whether or not the load should | 748 // Let the client have the final say into whether or not the load should |
| 753 // proceed. | 749 // proceed. |
| 754 DocumentLoader* documentLoader = masterDocumentLoader(); | 750 DocumentLoader* documentLoader = masterDocumentLoader(); |
| 755 if (documentLoader && documentLoader->subresourceFilter() && | 751 if (documentLoader && documentLoader->subresourceFilter() && |
| 756 type != Resource::MainResource && type != Resource::ImportResource && | 752 type != Resource::MainResource && type != Resource::ImportResource && |
| 757 !documentLoader->subresourceFilter()->allowLoad( | 753 !documentLoader->subresourceFilter()->allowLoad( |
| 758 url, resourceRequest.requestContext())) | 754 url, resourceRequest.requestContext())) |
| 759 return ResourceRequestBlockedReasonSubresourceFilter; | 755 return ResourceRequestBlockedReason::SubresourceFilter; |
| 760 | 756 |
| 761 return ResourceRequestBlockedReasonNone; | 757 return ResourceRequestBlockedReason::None; |
| 762 } | 758 } |
| 763 | 759 |
| 764 bool FrameFetchContext::isControlledByServiceWorker() const { | 760 bool FrameFetchContext::isControlledByServiceWorker() const { |
| 765 DCHECK(m_documentLoader || frame()->loader().documentLoader()); | 761 DCHECK(m_documentLoader || frame()->loader().documentLoader()); |
| 766 | 762 |
| 767 // Service workers are bypassed by suborigins (see | 763 // Service workers are bypassed by suborigins (see |
| 768 // https://w3c.github.io/webappsec-suborigins/). Since service worker | 764 // https://w3c.github.io/webappsec-suborigins/). Since service worker |
| 769 // controllers are assigned based on physical origin, without knowledge of | 765 // controllers are assigned based on physical origin, without knowledge of |
| 770 // whether the context is in a suborigin, it is necessary to explicitly bypass | 766 // whether the context is in a suborigin, it is necessary to explicitly bypass |
| 771 // service workers on a per-request basis. Additionally, it is necessary to | 767 // service workers on a per-request basis. Additionally, it is necessary to |
| (...skipping 251 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1023 response); | 1019 response); |
| 1024 } | 1020 } |
| 1025 | 1021 |
| 1026 DEFINE_TRACE(FrameFetchContext) { | 1022 DEFINE_TRACE(FrameFetchContext) { |
| 1027 visitor->trace(m_document); | 1023 visitor->trace(m_document); |
| 1028 visitor->trace(m_documentLoader); | 1024 visitor->trace(m_documentLoader); |
| 1029 FetchContext::trace(visitor); | 1025 FetchContext::trace(visitor); |
| 1030 } | 1026 } |
| 1031 | 1027 |
| 1032 } // namespace blink | 1028 } // namespace blink |
| OLD | NEW |