| OLD | NEW | 
|    1 /* |    1 /* | 
|    2  * Copyright (C) 2009 Google Inc. All rights reserved. |    2  * Copyright (C) 2009 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 24 matching lines...) Expand all  Loading... | 
|   35 #include "core/frame/LocalDOMWindow.h" |   35 #include "core/frame/LocalDOMWindow.h" | 
|   36 #include "core/frame/LocalFrame.h" |   36 #include "core/frame/LocalFrame.h" | 
|   37 #include "core/frame/Location.h" |   37 #include "core/frame/Location.h" | 
|   38 #include "core/frame/Settings.h" |   38 #include "core/frame/Settings.h" | 
|   39 #include "core/html/HTMLFrameElementBase.h" |   39 #include "core/html/HTMLFrameElementBase.h" | 
|   40 #include "core/workers/MainThreadWorkletGlobalScope.h" |   40 #include "core/workers/MainThreadWorkletGlobalScope.h" | 
|   41 #include "platform/weborigin/SecurityOrigin.h" |   41 #include "platform/weborigin/SecurityOrigin.h" | 
|   42  |   42  | 
|   43 namespace blink { |   43 namespace blink { | 
|   44  |   44  | 
|   45 static bool isOriginAccessibleFromDOMWindow(const SecurityOrigin* targetOrigin, 
     const LocalDOMWindow* accessingWindow) |   45 namespace { | 
 |   46  | 
 |   47 bool canAccessFrameInternal(const LocalDOMWindow* accessingWindow, const Securit
     yOrigin* targetFrameOrigin, const DOMWindow* targetWindow) | 
|   46 { |   48 { | 
|   47     return accessingWindow && accessingWindow->document()->getSecurityOrigin()->
     canAccessCheckSuborigins(targetOrigin); |   49     SECURITY_CHECK(!(targetWindow && targetWindow->frame()) | 
|   48 } |   50         || targetWindow == targetWindow->frame()->domWindow()); | 
|   49  |  | 
|   50 static bool canAccessFrame(v8::Isolate* isolate, const LocalDOMWindow* accessing
     Window, const SecurityOrigin* targetFrameOrigin, const DOMWindow* targetWindow, 
     ExceptionState& exceptionState) |  | 
|   51 { |  | 
|   52     ASSERT_WITH_SECURITY_IMPLICATION(!(targetWindow && targetWindow->frame()) ||
      targetWindow == targetWindow->frame()->domWindow()); |  | 
|   53  |   51  | 
|   54     // It's important to check that targetWindow is a LocalDOMWindow: it's |   52     // It's important to check that targetWindow is a LocalDOMWindow: it's | 
|   55     // possible for a remote frame and local frame to have the same security |   53     // possible for a remote frame and local frame to have the same security | 
|   56     // origin, depending on the model being used to allocate Frames between |   54     // origin, depending on the model being used to allocate Frames between | 
|   57     // processes. See https://crbug.com/601629. |   55     // processes. See https://crbug.com/601629. | 
|   58     if (targetWindow && targetWindow->isLocalDOMWindow() && isOriginAccessibleFr
     omDOMWindow(targetFrameOrigin, accessingWindow)) |   56     if (!(accessingWindow && targetWindow && targetWindow->isLocalDOMWindow())) | 
 |   57         return false; | 
 |   58  | 
 |   59     const SecurityOrigin* accessingOrigin = | 
 |   60         accessingWindow->document()->getSecurityOrigin(); | 
 |   61     if (!accessingOrigin->canAccessCheckSuborigins(targetFrameOrigin)) | 
 |   62         return false; | 
 |   63  | 
 |   64     // Notify the loader's client if the initial document has been accessed. | 
 |   65     LocalFrame* targetFrame = toLocalDOMWindow(targetWindow)->frame(); | 
 |   66     if (targetFrame->loader().stateMachine()->isDisplayingInitialEmptyDocument()
     ) | 
 |   67         targetFrame->loader().didAccessInitialDocument(); | 
 |   68  | 
 |   69     return true; | 
 |   70 } | 
 |   71  | 
 |   72 bool canAccessFrame(const LocalDOMWindow* accessingWindow, const SecurityOrigin*
      targetFrameOrigin, const DOMWindow* targetWindow, ExceptionState& exceptionStat
     e) | 
 |   73 { | 
 |   74     if (canAccessFrameInternal(accessingWindow, targetFrameOrigin, targetWindow)
     ) | 
|   59         return true; |   75         return true; | 
|   60  |   76  | 
|   61     if (targetWindow) |   77     if (targetWindow) | 
|   62         exceptionState.throwSecurityError(targetWindow->sanitizedCrossDomainAcce
     ssErrorMessage(accessingWindow), targetWindow->crossDomainAccessErrorMessage(acc
     essingWindow)); |   78         exceptionState.throwSecurityError(targetWindow->sanitizedCrossDomainAcce
     ssErrorMessage(accessingWindow), targetWindow->crossDomainAccessErrorMessage(acc
     essingWindow)); | 
|   63     return false; |   79     return false; | 
|   64 } |   80 } | 
|   65  |   81  | 
|   66 static bool canAccessFrame(v8::Isolate* isolate, const LocalDOMWindow* accessing
     Window, SecurityOrigin* targetFrameOrigin, const DOMWindow* targetWindow, Securi
     tyReportingOption reportingOption = ReportSecurityError) |   82 bool canAccessFrame(const LocalDOMWindow* accessingWindow, SecurityOrigin* targe
     tFrameOrigin, const DOMWindow* targetWindow, SecurityReportingOption reportingOp
     tion = ReportSecurityError) | 
|   67 { |   83 { | 
|   68     ASSERT_WITH_SECURITY_IMPLICATION(!(targetWindow && targetWindow->frame()) ||
      targetWindow == targetWindow->frame()->domWindow()); |   84     if (canAccessFrameInternal(accessingWindow, targetFrameOrigin, targetWindow)
     ) | 
|   69  |  | 
|   70     // It's important to check that targetWindow is a LocalDOMWindow: it's |  | 
|   71     // possible for a remote frame and local frame to have the same security |  | 
|   72     // origin, depending on the model being used to allocate Frames between |  | 
|   73     // processes. See https://crbug.com/601629. |  | 
|   74     if (targetWindow->isLocalDOMWindow() && isOriginAccessibleFromDOMWindow(targ
     etFrameOrigin, accessingWindow)) |  | 
|   75         return true; |   85         return true; | 
|   76  |   86  | 
|   77     if (reportingOption == ReportSecurityError && targetWindow) |   87     if (accessingWindow && targetWindow && reportingOption == ReportSecurityErro
     r) | 
|   78         accessingWindow->printErrorMessage(targetWindow->crossDomainAccessErrorM
     essage(accessingWindow)); |   88         accessingWindow->printErrorMessage(targetWindow->crossDomainAccessErrorM
     essage(accessingWindow)); | 
|   79     return false; |   89     return false; | 
|   80 } |   90 } | 
|   81  |   91  | 
 |   92 } // namespace | 
 |   93  | 
|   82 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const DOMWindow* target, ExceptionState& exceptionState) |   94 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const DOMWindow* target, ExceptionState& exceptionState) | 
|   83 { |   95 { | 
|   84     ASSERT(target); |   96     ASSERT(target); | 
|   85     const Frame* frame = target->frame(); |   97     const Frame* frame = target->frame(); | 
|   86     if (!frame || !frame->securityContext()) |   98     if (!frame || !frame->securityContext()) | 
|   87         return false; |   99         return false; | 
|   88     return canAccessFrame(isolate, accessingWindow, frame->securityContext()->ge
     tSecurityOrigin(), target, exceptionState); |  100     return canAccessFrame(accessingWindow, frame->securityContext()->getSecurity
     Origin(), target, exceptionState); | 
|   89 } |  101 } | 
|   90  |  102  | 
|   91 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const DOMWindow* target, SecurityReportingOption reportin
     gOption) |  103 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const DOMWindow* target, SecurityReportingOption reportin
     gOption) | 
|   92 { |  104 { | 
|   93     ASSERT(target); |  105     ASSERT(target); | 
|   94     const Frame* frame = target->frame(); |  106     const Frame* frame = target->frame(); | 
|   95     if (!frame || !frame->securityContext()) |  107     if (!frame || !frame->securityContext()) | 
|   96         return false; |  108         return false; | 
|   97     return canAccessFrame(isolate, accessingWindow, frame->securityContext()->ge
     tSecurityOrigin(), target, reportingOption); |  109     return canAccessFrame(accessingWindow, frame->securityContext()->getSecurity
     Origin(), target, reportingOption); | 
|   98 } |  110 } | 
|   99  |  111  | 
|  100 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const EventTarget* target, ExceptionState& exceptionState
     ) |  112 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const EventTarget* target, ExceptionState& exceptionState
     ) | 
|  101 { |  113 { | 
|  102     ASSERT(target); |  114     ASSERT(target); | 
|  103     const DOMWindow* window = target->toDOMWindow(); |  115     const DOMWindow* window = target->toDOMWindow(); | 
|  104     if (!window) { |  116     if (!window) { | 
|  105         // We only need to check the access to Window objects which are |  117         // We only need to check the access to Window objects which are | 
|  106         // cross-origin accessible.  If it's not a Window, the object's |  118         // cross-origin accessible.  If it's not a Window, the object's | 
|  107         // origin must always be the same origin (or it already leaked). |  119         // origin must always be the same origin (or it already leaked). | 
|  108         return true; |  120         return true; | 
|  109     } |  121     } | 
|  110     const Frame* frame = window->frame(); |  122     const Frame* frame = window->frame(); | 
|  111     if (!frame || !frame->securityContext()) |  123     if (!frame || !frame->securityContext()) | 
|  112         return false; |  124         return false; | 
|  113     return canAccessFrame(isolate, accessingWindow, frame->securityContext()->ge
     tSecurityOrigin(), window, exceptionState); |  125     return canAccessFrame(accessingWindow, frame->securityContext()->getSecurity
     Origin(), window, exceptionState); | 
|  114 } |  126 } | 
|  115  |  127  | 
|  116 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const Location* target, ExceptionState& exceptionState) |  128 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const Location* target, ExceptionState& exceptionState) | 
|  117 { |  129 { | 
|  118     ASSERT(target); |  130     ASSERT(target); | 
|  119     const Frame* frame = target->frame(); |  131     const Frame* frame = target->frame(); | 
|  120     if (!frame || !frame->securityContext()) |  132     if (!frame || !frame->securityContext()) | 
|  121         return false; |  133         return false; | 
|  122     return canAccessFrame(isolate, accessingWindow, frame->securityContext()->ge
     tSecurityOrigin(), frame->domWindow(), exceptionState); |  134     return canAccessFrame(accessingWindow, frame->securityContext()->getSecurity
     Origin(), frame->domWindow(), exceptionState); | 
|  123 } |  135 } | 
|  124  |  136  | 
|  125 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const Location* target, SecurityReportingOption reporting
     Option) |  137 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const Location* target, SecurityReportingOption reporting
     Option) | 
|  126 { |  138 { | 
|  127     ASSERT(target); |  139     ASSERT(target); | 
|  128     const Frame* frame = target->frame(); |  140     const Frame* frame = target->frame(); | 
|  129     if (!frame || !frame->securityContext()) |  141     if (!frame || !frame->securityContext()) | 
|  130         return false; |  142         return false; | 
|  131     return canAccessFrame(isolate, accessingWindow, frame->securityContext()->ge
     tSecurityOrigin(), frame->domWindow(), reportingOption); |  143     return canAccessFrame(accessingWindow, frame->securityContext()->getSecurity
     Origin(), frame->domWindow(), reportingOption); | 
|  132 } |  144 } | 
|  133  |  145  | 
|  134 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, v8::Local<v8::Co
     ntext> context, const ExecutionContext* executionContext, const MainThreadWorkle
     tGlobalScope* workletGlobalScope, SecurityReportingOption reportingOption) |  146 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, v8::Local<v8::Co
     ntext> context, const ExecutionContext* executionContext, const MainThreadWorkle
     tGlobalScope* workletGlobalScope, SecurityReportingOption reportingOption) | 
|  135 { |  147 { | 
|  136     DCHECK(executionContext); |  148     DCHECK(executionContext); | 
|  137     DOMWindow* domWindow = toDOMWindow(context); |  149     DOMWindow* domWindow = toDOMWindow(context); | 
|  138     if (executionContext->isMainThreadWorkletGlobalScope()) { |  150     if (executionContext->isMainThreadWorkletGlobalScope()) { | 
|  139         Frame* callingFrame = toMainThreadWorkletGlobalScope(executionContext)->
     frame(); |  151         Frame* callingFrame = toMainThreadWorkletGlobalScope(executionContext)->
     frame(); | 
|  140         domWindow = callingFrame ? callingFrame->domWindow() : nullptr; |  152         domWindow = callingFrame ? callingFrame->domWindow() : nullptr; | 
|  141     } |  153     } | 
|  142  |  154  | 
|  143     DCHECK(workletGlobalScope); |  155     DCHECK(workletGlobalScope); | 
|  144     const Frame* workletGlobalScopeFrame = workletGlobalScope->frame(); |  156     const Frame* workletGlobalScopeFrame = workletGlobalScope->frame(); | 
|  145     if (!workletGlobalScopeFrame || !workletGlobalScopeFrame->securityContext()) |  157     if (!workletGlobalScopeFrame || !workletGlobalScopeFrame->securityContext()) | 
|  146         return false; |  158         return false; | 
|  147  |  159  | 
|  148     return domWindow && canAccessFrame(isolate, toLocalDOMWindow(domWindow), wor
     kletGlobalScopeFrame->securityContext()->getSecurityOrigin(), workletGlobalScope
     Frame->domWindow(), reportingOption); |  160     return domWindow && canAccessFrame(toLocalDOMWindow(domWindow), workletGloba
     lScopeFrame->securityContext()->getSecurityOrigin(), workletGlobalScopeFrame->do
     mWindow(), reportingOption); | 
|  149 } |  161 } | 
|  150  |  162  | 
|  151 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, v8::Local<v8::Co
     ntext> calling, v8::Local<v8::Context> target, SecurityReportingOption reporting
     Option) |  163 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, v8::Local<v8::Co
     ntext> calling, v8::Local<v8::Context> target, SecurityReportingOption reporting
     Option) | 
|  152 { |  164 { | 
|  153     ExecutionContext* targetExecutionContext = toExecutionContext(target); |  165     ExecutionContext* targetExecutionContext = toExecutionContext(target); | 
|  154     DCHECK(targetExecutionContext); |  166     DCHECK(targetExecutionContext); | 
|  155  |  167  | 
|  156     ExecutionContext* callingExecutionContext = toExecutionContext(calling); |  168     ExecutionContext* callingExecutionContext = toExecutionContext(calling); | 
|  157     DCHECK(callingExecutionContext); |  169     DCHECK(callingExecutionContext); | 
|  158  |  170  | 
|  159     if (targetExecutionContext->isMainThreadWorkletGlobalScope()) |  171     if (targetExecutionContext->isMainThreadWorkletGlobalScope()) | 
|  160         return shouldAllowAccessTo(isolate, calling, callingExecutionContext, to
     MainThreadWorkletGlobalScope(targetExecutionContext), DoNotReportSecurityError); |  172         return shouldAllowAccessTo(isolate, calling, callingExecutionContext, to
     MainThreadWorkletGlobalScope(targetExecutionContext), DoNotReportSecurityError); | 
|  161  |  173  | 
|  162     if (callingExecutionContext->isMainThreadWorkletGlobalScope()) |  174     if (callingExecutionContext->isMainThreadWorkletGlobalScope()) | 
|  163         return shouldAllowAccessTo(isolate, target, targetExecutionContext, toMa
     inThreadWorkletGlobalScope(callingExecutionContext), DoNotReportSecurityError); |  175         return shouldAllowAccessTo(isolate, target, targetExecutionContext, toMa
     inThreadWorkletGlobalScope(callingExecutionContext), DoNotReportSecurityError); | 
|  164  |  176  | 
|  165     DOMWindow* window = toDOMWindow(target); |  177     DOMWindow* window = toDOMWindow(target); | 
|  166     return window && shouldAllowAccessTo(isolate, toLocalDOMWindow(toDOMWindow(c
     alling)), window, DoNotReportSecurityError); |  178     return window && shouldAllowAccessTo(isolate, toLocalDOMWindow(toDOMWindow(c
     alling)), window, DoNotReportSecurityError); | 
|  167 } |  179 } | 
|  168  |  180  | 
|  169 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const Node* target, ExceptionState& exceptionState) |  181 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const Node* target, ExceptionState& exceptionState) | 
|  170 { |  182 { | 
|  171     if (!target) |  183     if (!target) | 
|  172         return false; |  184         return false; | 
|  173     return canAccessFrame(isolate, accessingWindow, target->document().getSecuri
     tyOrigin(), target->document().domWindow(), exceptionState); |  185     return canAccessFrame(accessingWindow, target->document().getSecurityOrigin(
     ), target->document().domWindow(), exceptionState); | 
|  174 } |  186 } | 
|  175  |  187  | 
|  176 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const Node* target, SecurityReportingOption reportingOpti
     on) |  188 bool BindingSecurity::shouldAllowAccessTo(v8::Isolate* isolate, const LocalDOMWi
     ndow* accessingWindow, const Node* target, SecurityReportingOption reportingOpti
     on) | 
|  177 { |  189 { | 
|  178     if (!target) |  190     if (!target) | 
|  179         return false; |  191         return false; | 
|  180     return canAccessFrame(isolate, accessingWindow, target->document().getSecuri
     tyOrigin(), target->document().domWindow(), reportingOption); |  192     return canAccessFrame(accessingWindow, target->document().getSecurityOrigin(
     ), target->document().domWindow(), reportingOption); | 
|  181 } |  193 } | 
|  182  |  194  | 
|  183 bool BindingSecurity::shouldAllowAccessToFrame(v8::Isolate* isolate, const Local
     DOMWindow* accessingWindow, const Frame* target, SecurityReportingOption reporti
     ngOption) |  195 bool BindingSecurity::shouldAllowAccessToFrame(v8::Isolate* isolate, const Local
     DOMWindow* accessingWindow, const Frame* target, SecurityReportingOption reporti
     ngOption) | 
|  184 { |  196 { | 
|  185     if (!target || !target->securityContext()) |  197     if (!target || !target->securityContext()) | 
|  186         return false; |  198         return false; | 
|  187     return canAccessFrame(isolate, accessingWindow, target->securityContext()->g
     etSecurityOrigin(), target->domWindow(), reportingOption); |  199     return canAccessFrame(accessingWindow, target->securityContext()->getSecurit
     yOrigin(), target->domWindow(), reportingOption); | 
|  188 } |  200 } | 
|  189  |  201  | 
|  190 } // namespace blink |  202 } // namespace blink | 
| OLD | NEW |