⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 276230 in webkit


Ignore:
Timestamp:
Apr 18, 2021, 9:42:06 AM (5 years ago)
Author:
youenn@apple.com
Message:

Blob URLs should use for their owner origin for CSP checks
https://bugs.webkit.org/show_bug.cgi?id=224535
<rdar://76458106>

Reviewed by Alex Christensen.

Source/WebCore:

Before the patch, we were checking blob origin directly with ancestors.
As per https://w3c.github.io/webappsec-csp/#match-url-to-source-expression step 4.1,
we need to get the URL origin, which by spec is the origin of the blob creator.
We only do this for navigation loads as script loads should be kept the current way, as a cross-site scripting protection,
and to remain compatible with other browsers.

Make some refactoring to add helper routines to get origin and secure context state of blob URLs in BlobURL.
Make use of it in MixedContentChecker as a refactoring.
Make use of the helper routine in ContentSecurityPolicySource::matches to fix the bug.

Test: http/tests/security/frame-src-and-blob-download.https.html

  • fileapi/BlobURL.cpp:

(WebCore::blobOwner):
(WebCore::BlobURL::getOriginURL):
(WebCore::BlobURL::isSecureBlobURL):

  • fileapi/BlobURL.h:
  • fileapi/ThreadableBlobRegistry.cpp:

(WebCore::isBlobURLContainsNullOrigin):

  • loader/MixedContentChecker.cpp:

(WebCore::MixedContentChecker::isMixedContent):

  • page/SecurityOrigin.cpp:

(WebCore::SecurityOrigin::isSecure):

  • page/csp/ContentSecurityPolicy.cpp:

(WebCore::ContentSecurityPolicy::urlMatchesSelf const):

  • page/csp/ContentSecurityPolicy.h:
  • page/csp/ContentSecurityPolicySourceList.cpp:

(WebCore::ContentSecurityPolicySourceList::matches const):

LayoutTests:

  • http/tests/security/frame-src-and-blob-download.https-expected.txt: Added.
  • http/tests/security/frame-src-and-blob-download.https.html:
  • http/tests/security/resources/frame-src-and-blob-download-frame.html: Added.
  • platform/mac-wk1/TestExpectations:
  • platform/win/TestExpectations:
Location:
trunk
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • trunk/LayoutTests/ChangeLog

    r276216 r276230  
     12021-04-18  Youenn Fablet  <youenn@apple.com>
     2
     3        Blob URLs should use for their owner origin for CSP checks
     4        https://bugs.webkit.org/show_bug.cgi?id=224535
     5        <rdar://76458106>
     6
     7        Reviewed by Alex Christensen.
     8
     9        * http/tests/security/frame-src-and-blob-download.https-expected.txt: Added.
     10        * http/tests/security/frame-src-and-blob-download.https.html:
     11        * http/tests/security/resources/frame-src-and-blob-download-frame.html: Added.
     12        * platform/mac-wk1/TestExpectations:
     13        * platform/win/TestExpectations:
     14
    1152021-04-17  Tim Nguyen  <ntim@apple.com>
    216
  • trunk/LayoutTests/platform/mac-wk1/TestExpectations

    r276166 r276230  
    138138webkit.org/b/156069 http/tests/security/anchor-download-octet-stream-no-extension.html [ Skip ]
    139139webkit.org/b/156069 http/wpt/html/semantics/text-level-semantics/the-a-element/a-download-click-404.html [ Skip ]
     140http/tests/security/frame-src-and-blob-download.https.html [ Skip ]
    140141
    141142# Not supported on WK1
  • trunk/LayoutTests/platform/win/TestExpectations

    r276105 r276230  
    225225webkit.org/b/29287 http/tests/local/blob/send-hybrid-blob.html [ Skip ]
    226226webkit.org/b/29287 http/tests/local/formdata/ [ Skip ]
     227http/tests/security/frame-src-and-blob-download.https.html [ Skip ]
    227228
    228229# Software keyboard is not supported.
  • trunk/Source/WebCore/ChangeLog

    r276228 r276230  
     12021-04-18  Youenn Fablet  <youenn@apple.com>
     2
     3        Blob URLs should use for their owner origin for CSP checks
     4        https://bugs.webkit.org/show_bug.cgi?id=224535
     5        <rdar://76458106>
     6
     7        Reviewed by Alex Christensen.
     8
     9        Before the patch, we were checking blob origin directly with ancestors.
     10        As per https://w3c.github.io/webappsec-csp/#match-url-to-source-expression step 4.1,
     11        we need to get the URL origin, which by spec is the origin of the blob creator.
     12        We only do this for navigation loads as script loads should be kept the current way, as a cross-site scripting protection,
     13        and to remain compatible with other browsers.
     14
     15        Make some refactoring to add helper routines to get origin and secure context state of blob URLs in BlobURL.
     16        Make use of it in MixedContentChecker as a refactoring.
     17        Make use of the helper routine in ContentSecurityPolicySource::matches to fix the bug.
     18
     19        Test: http/tests/security/frame-src-and-blob-download.https.html
     20
     21        * fileapi/BlobURL.cpp:
     22        (WebCore::blobOwner):
     23        (WebCore::BlobURL::getOriginURL):
     24        (WebCore::BlobURL::isSecureBlobURL):
     25        * fileapi/BlobURL.h:
     26        * fileapi/ThreadableBlobRegistry.cpp:
     27        (WebCore::isBlobURLContainsNullOrigin):
     28        * loader/MixedContentChecker.cpp:
     29        (WebCore::MixedContentChecker::isMixedContent):
     30        * page/SecurityOrigin.cpp:
     31        (WebCore::SecurityOrigin::isSecure):
     32        * page/csp/ContentSecurityPolicy.cpp:
     33        (WebCore::ContentSecurityPolicy::urlMatchesSelf const):
     34        * page/csp/ContentSecurityPolicy.h:
     35        * page/csp/ContentSecurityPolicySourceList.cpp:
     36        (WebCore::ContentSecurityPolicySourceList::matches const):
     37
    1382021-04-18  Cathie Chen  <cathiechen@igalia.com>
    239
  • trunk/Source/WebCore/fileapi/BlobURL.cpp

    r262421 r276230  
    3232
    3333#include "BlobURL.h"
     34#include "Document.h"
     35#include "SecurityOrigin.h"
     36#include "ThreadableBlobRegistry.h"
    3437
    3538#include <wtf/URL.h>
    36 #include "SecurityOrigin.h"
    3739#include <wtf/UUID.h>
    3840#include <wtf/text/WTFString.h>
     
    5355}
    5456
    55 String BlobURL::getOrigin(const URL& url)
     57static const Document* blobOwner(const SecurityOrigin& blobOrigin)
     58{
     59    if (!isMainThread())
     60        return nullptr;
     61
     62    for (const auto* document : Document::allDocuments()) {
     63        if (&document->securityOrigin() == &blobOrigin)
     64            return document;
     65    }
     66    return nullptr;
     67}
     68
     69URL BlobURL::getOriginURL(const URL& url)
    5670{
    5771    ASSERT(url.protocolIs(kBlobProtocol));
    5872
    59     unsigned startIndex = url.pathStart();
    60     unsigned endIndex = url.pathAfterLastSlash();
    61     return url.string().substring(startIndex, endIndex - startIndex - 1);
     73    if (auto blobOrigin = ThreadableBlobRegistry::getCachedOrigin(url)) {
     74        if (auto* document = blobOwner(*blobOrigin))
     75            return document->url();
     76    }
     77    return SecurityOrigin::extractInnerURL(url);
     78}
     79
     80bool BlobURL::isSecureBlobURL(const URL& url)
     81{
     82    ASSERT(url.protocolIs(kBlobProtocol));
     83
     84    // As per https://github.com/w3c/webappsec-mixed-content/issues/41, Blob URL is secure if the document that created it is secure.
     85    if (auto origin = ThreadableBlobRegistry::getCachedOrigin(url)) {
     86        if (auto* document = blobOwner(*origin))
     87            return document->isSecureContext();
     88    }
     89    return SecurityOrigin::isSecure(url);
    6290}
    6391
  • trunk/Source/WebCore/fileapi/BlobURL.h

    r262421 r276230  
    5050    static URL createPublicURL(SecurityOrigin*);
    5151    static URL createInternalURL();
    52     static String getOrigin(const URL&);
     52
     53    static URL getOriginURL(const URL&);
     54    static bool isSecureBlobURL(const URL&);
    5355
    5456private:
  • trunk/Source/WebCore/fileapi/ThreadableBlobRegistry.cpp

    r274306 r276230  
    9595{
    9696    ASSERT(url.protocolIsBlob());
    97     return BlobURL::getOrigin(url) == "null";
     97    unsigned startIndex = url.pathStart();
     98    unsigned endIndex = url.pathAfterLastSlash();
     99    return url.string().substring(startIndex, endIndex - startIndex - 1) == "null";
    98100}
    99101
  • trunk/Source/WebCore/loader/MixedContentChecker.cpp

    r273879 r276230  
    3838#include "SecurityOrigin.h"
    3939#include "Settings.h"
    40 #include "ThreadableBlobRegistry.h"
    4140#include <wtf/text/CString.h>
    4241#include <wtf/text/WTFString.h>
     
    4948    if (securityOrigin.protocol() != "https")
    5049        return false; // We only care about HTTPS security origins.
    51 
    52     if (url.protocolIsBlob()) {
    53         // As per https://github.com/w3c/webappsec-mixed-content/issues/41, Blob URL is secure if the document that created it is secure.
    54         // This code path is specific to opaque origins.
    55         if (auto origin = ThreadableBlobRegistry::getCachedOrigin(url)) {
    56             const Document* blobDocument = nullptr;
    57             for (const auto* document : Document::allDocuments()) {
    58                 if (&document->securityOrigin() == origin.get()) {
    59                     blobDocument = document;
    60                     break;
    61                 }
    62             }
    63             if (blobDocument && blobDocument->isSecureContext())
    64                 return false;
    65         }
    66     }
    6750
    6851    // We're in a secure context, so |url| is mixed content if it's insecure.
  • trunk/Source/WebCore/page/SecurityOrigin.cpp

    r275395 r276230  
    266266
    267267    // URLs that wrap inner URLs are secure if those inner URLs are secure.
    268     if (shouldUseInnerURL(url) && LegacySchemeRegistry::shouldTreatURLSchemeAsSecure(extractInnerURL(url).protocol().toStringWithoutCopying()))
    269         return true;
     268    if (shouldUseInnerURL(url))
     269        return LegacySchemeRegistry::shouldTreatURLSchemeAsSecure(extractInnerURL(url).protocol().toStringWithoutCopying()) || BlobURL::isSecureBlobURL(url);
    270270
    271271    return false;
  • trunk/Source/WebCore/page/csp/ContentSecurityPolicy.cpp

    r273820 r276230  
    2828#include "ContentSecurityPolicy.h"
    2929
     30#include "BlobURL.h"
    3031#include "ContentSecurityPolicyClient.h"
    3132#include "ContentSecurityPolicyDirective.h"
     
    278279}
    279280
    280 bool ContentSecurityPolicy::urlMatchesSelf(const URL& url) const
    281 {
     281bool ContentSecurityPolicy::urlMatchesSelf(const URL& url, bool forFrameSrc) const
     282{
     283    // As per https://w3c.github.io/webappsec-csp/#match-url-to-source-expression, we compare the URL origin with the policy origin.
     284    // We get origin using https://url.spec.whatwg.org/#concept-url-origin which has specific blob URLs treatment as follow.
     285    if (forFrameSrc && url.protocolIsBlob())
     286        return m_selfSource->matches(BlobURL::getOriginURL(url));
    282287    return m_selfSource->matches(url);
    283288}
  • trunk/Source/WebCore/page/csp/ContentSecurityPolicy.h

    r273820 r276230  
    139139    void reportInvalidPathCharacter(const String& directiveName, const String& value, const char) const;
    140140    void reportInvalidSourceExpression(const String& directiveName, const String& source) const;
    141     bool urlMatchesSelf(const URL&) const;
     141    bool urlMatchesSelf(const URL&, bool forFrameSrc) const;
    142142    bool allowContentSecurityPolicySourceStarToMatchAnyProtocol() const;
    143143
  • trunk/Source/WebCore/page/csp/ContentSecurityPolicySourceList.cpp

    r265129 r276230  
    133133        return true;
    134134
    135     if (m_allowSelf && m_policy.urlMatchesSelf(url))
     135    if (m_allowSelf && m_policy.urlMatchesSelf(url, equalIgnoringASCIICase(m_directiveName, ContentSecurityPolicyDirectiveNames::frameSrc)
     136))
    136137        return true;
    137138
Note: See TracChangeset for help on using the changeset viewer.