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