Changeset 53049 in webkit


Ignore:
Timestamp:
Jan 10, 2010 12:10:00 AM (14 years ago)
Author:
abarth@webkit.org
Message:

2010-01-09 Adam Barth <abarth@webkit.org>

Reviewed by Darin Adler.

Unify origin sandbox flag with m_noAccess in SecurityOrigin
https://bugs.webkit.org/show_bug.cgi?id=32372

It turns out the SandboxOrigin bit is slightly different than the
unique origin concept because the sandbox bit is inherited by iframes.
These concepts are separate in the spec, so I think it's ok to keep
them separate in the implementation as well.

No new tests because there is no behavior change.

  • dom/Document.cpp: (WebCore::Document::cookie): (WebCore::Document::setCookie):
  • loader/CrossOriginAccessControl.cpp: (WebCore::passesAccessControlCheck):
  • page/SecurityOrigin.cpp: (WebCore::schemesWithUniqueOrigins): (WebCore::SecurityOrigin::SecurityOrigin): (WebCore::SecurityOrigin::canAccess): (WebCore::SecurityOrigin::canRequest): (WebCore::SecurityOrigin::taintsCanvas): (WebCore::SecurityOrigin::setSandboxFlags): (WebCore::SecurityOrigin::toString): (WebCore::SecurityOrigin::registerURLSchemeAsNoAccess): (WebCore::SecurityOrigin::shouldTreatURLSchemeAsNoAccess):
  • page/SecurityOrigin.h: (WebCore::SecurityOrigin::canAccessDatabase): (WebCore::SecurityOrigin::canAccessStorage): (WebCore::SecurityOrigin::canAccessCookies): (WebCore::SecurityOrigin::isUnique):
Location:
trunk/WebCore
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r53046 r53049  
     12010-01-09  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Darin Adler.
     4
     5        Unify origin sandbox flag with m_noAccess in SecurityOrigin
     6        https://bugs.webkit.org/show_bug.cgi?id=32372
     7
     8        It turns out the SandboxOrigin bit is slightly different than the
     9        unique origin concept because the sandbox bit is inherited by iframes.
     10        These concepts are separate in the spec, so I think it's ok to keep
     11        them separate in the implementation as well.
     12
     13        No new tests because there is no behavior change.
     14
     15        * dom/Document.cpp:
     16        (WebCore::Document::cookie):
     17        (WebCore::Document::setCookie):
     18        * loader/CrossOriginAccessControl.cpp:
     19        (WebCore::passesAccessControlCheck):
     20        * page/SecurityOrigin.cpp:
     21        (WebCore::schemesWithUniqueOrigins):
     22        (WebCore::SecurityOrigin::SecurityOrigin):
     23        (WebCore::SecurityOrigin::canAccess):
     24        (WebCore::SecurityOrigin::canRequest):
     25        (WebCore::SecurityOrigin::taintsCanvas):
     26        (WebCore::SecurityOrigin::setSandboxFlags):
     27        (WebCore::SecurityOrigin::toString):
     28        (WebCore::SecurityOrigin::registerURLSchemeAsNoAccess):
     29        (WebCore::SecurityOrigin::shouldTreatURLSchemeAsNoAccess):
     30        * page/SecurityOrigin.h:
     31        (WebCore::SecurityOrigin::canAccessDatabase):
     32        (WebCore::SecurityOrigin::canAccessStorage):
     33        (WebCore::SecurityOrigin::canAccessCookies):
     34        (WebCore::SecurityOrigin::isUnique):
     35
    1362010-01-09  Adam Barth  <abarth@webkit.org>
    237
  • trunk/WebCore/dom/Document.cpp

    r53027 r53049  
    30693069    // browsing context.
    30703070
    3071     if (securityOrigin()->isSandboxed(SandboxOrigin)) {
     3071    if (!securityOrigin()->canAccessCookies()) {
    30723072        ec = SECURITY_ERR;
    30733073        return String();
     
    30903090    // browsing context.
    30913091
    3092     if (securityOrigin()->isSandboxed(SandboxOrigin)) {
     3092    if (!securityOrigin()->canAccessCookies()) {
    30933093        ec = SECURITY_ERR;
    30943094        return;
  • trunk/WebCore/loader/CrossOriginAccessControl.cpp

    r51577 r53049  
    101101        return true;
    102102
    103     // A sandboxed frame has a unique origin (for same-origin purposes).
    104     if (securityOrigin->isSandboxed(SandboxOrigin))
     103    if (securityOrigin->isUnique())
    105104        return false;
    106105
  • trunk/WebCore/page/SecurityOrigin.cpp

    r51703 r53049  
    6666}
    6767
    68 static URLSchemesMap& noAccessSchemes()
    69 {
    70     DEFINE_STATIC_LOCAL(URLSchemesMap, noAccessSchemes, ());
    71 
    72     if (noAccessSchemes.isEmpty())
    73         noAccessSchemes.add("data");
    74 
    75     return noAccessSchemes;
     68static URLSchemesMap& schemesWithUniqueOrigins()
     69{
     70    DEFINE_STATIC_LOCAL(URLSchemesMap, schemesWithUniqueOrigins, ());
     71
     72    // This is a willful violation of HTML5.
     73    // See https://bugs.webkit.org/show_bug.cgi?id=11885
     74    if (schemesWithUniqueOrigins.isEmpty())
     75        schemesWithUniqueOrigins.add("data");
     76
     77    return schemesWithUniqueOrigins;
    7678}
    7779
    7880SecurityOrigin::SecurityOrigin(const KURL& url)
    79     : m_protocol(url.protocol().isNull() ? "" : url.protocol().lower())
     81    : m_sandboxFlags(SandboxNone)
     82    , m_protocol(url.protocol().isNull() ? "" : url.protocol().lower())
    8083    , m_host(url.host().isNull() ? "" : url.host().lower())
    8184    , m_port(url.port())
    82     , m_sandboxFlags(SandboxNone)
    83     , m_noAccess(false)
     85    , m_isUnique(false)
    8486    , m_universalAccess(false)
    8587    , m_domainWasSetInDOM(false)
     
    9193    // Some URLs are not allowed access to anything other than themselves.
    9294    if (shouldTreatURLSchemeAsNoAccess(m_protocol))
    93         m_noAccess = true;
     95        m_isUnique = true;
     96
     97    // If this ASSERT becomes false in the future, please consider the impact
     98    // of m_sandoxFlags on m_isUnique.
     99    ASSERT(m_sandboxFlags == SandboxNone);
    94100
    95101    // document.domain starts as m_host, but can be set by the DOM.
     
    101107        // Directories should never be readable.
    102108        if (!url.hasPath() || url.path().endsWith("/"))
    103             m_noAccess = true;
     109            m_isUnique = true;
    104110    }
    105111
     
    109115
    110116SecurityOrigin::SecurityOrigin(const SecurityOrigin* other)
    111     : m_protocol(other->m_protocol.threadsafeCopy())
     117    : m_sandboxFlags(other->m_sandboxFlags)
     118    , m_protocol(other->m_protocol.threadsafeCopy())
    112119    , m_host(other->m_host.threadsafeCopy())
    113120    , m_domain(other->m_domain.threadsafeCopy())
    114121    , m_port(other->m_port)
    115     , m_sandboxFlags(other->m_sandboxFlags)
    116     , m_noAccess(other->m_noAccess)
     122    , m_isUnique(other->m_isUnique)
    117123    , m_universalAccess(other->m_universalAccess)
    118124    , m_domainWasSetInDOM(other->m_domainWasSetInDOM)
     
    154160        return true;
    155161
    156     if (m_noAccess || other->m_noAccess || isSandboxed(SandboxOrigin) || other->isSandboxed(SandboxOrigin))
     162    if (isUnique() || other->isUnique())
    157163        return false;
    158164
    159165    // Here are two cases where we should permit access:
    160166    //
    161     // 1) Neither document has set document.domain.  In this case, we insist
     167    // 1) Neither document has set document.domain. In this case, we insist
    162168    //    that the scheme, host, and port of the URLs match.
    163169    //
    164     // 2) Both documents have set document.domain.  In this case, we insist
     170    // 2) Both documents have set document.domain. In this case, we insist
    165171    //    that the documents have set document.domain to the same value and
    166172    //    that the scheme of the URLs match.
     
    195201        return true;
    196202
    197     if (m_noAccess || isSandboxed(SandboxOrigin))
     203    if (isUnique())
    198204        return false;
    199205
    200206    RefPtr<SecurityOrigin> targetOrigin = SecurityOrigin::create(url);
    201     if (targetOrigin->m_noAccess)
     207    if (targetOrigin->isUnique())
    202208        return false;
    203209
     
    222228        return false;
    223229
    224     // This method exists because we treat data URLs as noAccess, contrary
    225     // to the current (9/19/2009) draft of the HTML5 specification.  We still
    226     // want to let folks paint data URLs onto untainted canvases, so we special
    227     // case data URLs below.  If we change to match HTML5 w.r.t. data URL
    228     // security, then we can remove this method in favor of !canRequest.
     230    // This function exists because we treat data URLs as having a unique origin,
     231    // contrary to the current (9/19/2009) draft of the HTML5 specification.
     232    // We still want to let folks paint data URLs onto untainted canvases, so
     233    // we special case data URLs below. If we change to match HTML5 w.r.t.
     234    // data URL security, then we can remove this function in favor of
     235    // !canRequest.
    229236    if (url.protocolIs("data"))
    230237        return false;
     
    249256void SecurityOrigin::grantLoadLocalResources()
    250257{
    251     // This method exists only to support backwards compatibility with older
    252     // versions of WebKit.  Granting privileges to some, but not all, documents
     258    // This function exists only to support backwards compatibility with older
     259    // versions of WebKit. Granting privileges to some, but not all, documents
    253260    // in a SecurityOrigin is a security hazard because the documents without
    254261    // the privilege can obtain the privilege by injecting script into the
     
    263270}
    264271
     272void SecurityOrigin::setSandboxFlags(SandboxFlags flags)
     273{
     274    m_sandboxFlags = flags;
     275    if (isSandboxed(SandboxOrigin))
     276        m_isUnique = true;
     277
     278    // Although you might think that we should set m_isUnique to false when
     279    // flags doesn't contain SandboxOrigin, that's not actually the right
     280    // behavior. We're supposed to freeze the origin of a document when it
     281    // is created, even if the sandbox flags change after that point in time.
     282    //
     283    // FIXME: Our current behavior here is buggy because we need to
     284    //        distinguish between the sandbox flags at creation and the
     285    //        sandbox flags that might come about later.
     286}
     287
    265288bool SecurityOrigin::isLocal() const
    266289{
     
    283306        return "null";
    284307
    285     if (m_noAccess || isSandboxed(SandboxOrigin))
     308    if (isUnique())
    286309        return "null";
    287310
     
    441464void SecurityOrigin::registerURLSchemeAsNoAccess(const String& scheme)
    442465{
    443     noAccessSchemes().add(scheme);
     466    schemesWithUniqueOrigins().add(scheme);
    444467}
    445468
    446469bool SecurityOrigin::shouldTreatURLSchemeAsNoAccess(const String& scheme)
    447470{
    448     return noAccessSchemes().contains(scheme);
     471    return schemesWithUniqueOrigins().contains(scheme);
    449472}
    450473
  • trunk/WebCore/page/SecurityOrigin.h

    r53038 r53049  
    5353    static PassRefPtr<SecurityOrigin> createEmpty();
    5454
    55     // Create a deep copy of this SecurityOrigin.  This method is useful
     55    // Create a deep copy of this SecurityOrigin. This method is useful
    5656    // when marshalling a SecurityOrigin to another thread.
    5757    PassRefPtr<SecurityOrigin> threadsafeCopy();
    5858
    59     // Set the domain property of this security origin to newDomain.  This
     59    // Set the domain property of this security origin to newDomain. This
    6060    // function does not check whether newDomain is a suffix of the current
    61     // domain.  The caller is responsible for validating newDomain.
     61    // domain. The caller is responsible for validating newDomain.
    6262    void setDomainFromDOM(const String& newDomain);
    6363    bool domainWasSetInDOM() const { return m_domainWasSetInDOM; }
     
    6969
    7070    // Returns true if this SecurityOrigin can script objects in the given
    71     // SecurityOrigin.  For example, call this function before allowing
     71    // SecurityOrigin. For example, call this function before allowing
    7272    // script from one security origin to read or write objects from
    7373    // another SecurityOrigin.
     
    7575
    7676    // Returns true if this SecurityOrigin can read content retrieved from
    77     // the given URL.  For example, call this function before issuing
     77    // the given URL. For example, call this function before issuing
    7878    // XMLHttpRequests.
    7979    bool canRequest(const KURL&) const;
    8080
    8181    // Returns true if drawing an image from this URL taints a canvas from
    82     // this security origin.  For example, call this function before
     82    // this security origin. For example, call this function before
    8383    // drawing an image onto an HTML canvas element with the drawImage API.
    8484    bool taintsCanvas(const KURL&) const;
     
    109109    // Explicitly grant the ability to access very other SecurityOrigin.
    110110    //
    111     // WARNING: This is an extremely powerful ability.  Use with caution!
     111    // WARNING: This is an extremely powerful ability. Use with caution!
    112112    void grantUniversalAccess();
    113113
    114     // Sandboxing status as determined by the frame.
    115     void setSandboxFlags(SandboxFlags flags) { m_sandboxFlags = flags; }
     114    void setSandboxFlags(SandboxFlags);
    116115    bool isSandboxed(SandboxFlags mask) const { return m_sandboxFlags & mask; }
    117116
    118     bool canAccessDatabase() const { return !isSandboxed(SandboxOrigin); }
    119     bool canAccessStorage() const { return !isSandboxed(SandboxOrigin); }
     117    bool canAccessDatabase() const { return !isUnique(); }
     118    bool canAccessStorage() const { return !isUnique(); }
     119    bool canAccessCookies() const { return !isUnique(); }
    120120
    121121    bool isSecureTransitionTo(const KURL&) const;
     
    129129    bool isEmpty() const;
    130130
    131     // Convert this SecurityOrigin into a string.  The string
     131    // The origin is a globally unique identifier assigned when the Document is
     132    // created. http://www.whatwg.org/specs/web-apps/current-work/#sandboxOrigin
     133    //
     134    // There's a subtle difference between a unique origin and an origin that
     135    // has the SandboxOrigin flag set. The latter implies the former, and, in
     136    // addition, the SandboxOrigin flag is inherited by iframes.
     137    bool isUnique() const { return m_isUnique; }
     138
     139    // Convert this SecurityOrigin into a string. The string
    132140    // representation of a SecurityOrigin is similar to a URL, except it
    133     // lacks a path component.  The string representation does not encode
     141    // lacks a path component. The string representation does not encode
    134142    // the value of the SecurityOrigin's domain property.
    135143    //
    136     // When using the string value, it's important to remember that it
    137     // might be "null".  This happens when this SecurityOrigin has
    138     // noAccess to other SecurityOrigins.  For example, this SecurityOrigin
    139     // might have come from a data URL, the SecurityOrigin might be empty,
    140     // or we might have explicitly decided that we
    141     // shouldTreatURLSchemeAsNoAccess.
     144    // When using the string value, it's important to remember that it might be
     145    // "null". This happens when this SecurityOrigin is unique. For example,
     146    // this SecurityOrigin might have come from a sandboxed iframe, the
     147    // SecurityOrigin might be empty, or we might have explicitly decided that
     148    // we shouldTreatURLSchemeAsNoAccess.
    142149    String toString() const;
    143150
     
    147154
    148155    // This method checks for equality between SecurityOrigins, not whether
    149     // one origin can access another.  It is used for hash table keys.
     156    // one origin can access another. It is used for hash table keys.
    150157    // For access checks, use canAccess().
    151158    // FIXME: If this method is really only useful for hash table keys, it
     
    184191    explicit SecurityOrigin(const SecurityOrigin*);
    185192
     193    SandboxFlags m_sandboxFlags;
    186194    String m_protocol;
    187195    String m_host;
    188196    String m_domain;
    189197    unsigned short m_port;
    190     SandboxFlags m_sandboxFlags;
    191     bool m_noAccess;
     198    bool m_isUnique;
    192199    bool m_universalAccess;
    193200    bool m_domainWasSetInDOM;
Note: See TracChangeset for help on using the changeset viewer.