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