| 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 15 matching lines...) Expand all Loading... |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "bindings/core/v8/BindingSecurity.h" | 31 #include "bindings/core/v8/BindingSecurity.h" |
| 32 | 32 |
| 33 #include "bindings/core/v8/ExceptionState.h" | 33 #include "bindings/core/v8/ExceptionState.h" |
| 34 #include "bindings/core/v8/V8BindingForCore.h" | 34 #include "bindings/core/v8/V8BindingForCore.h" |
| 35 #include "bindings/core/v8/V8Location.h" | 35 #include "bindings/core/v8/V8Location.h" |
| 36 #include "bindings/core/v8/V8Window.h" |
| 36 #include "core/dom/Document.h" | 37 #include "core/dom/Document.h" |
| 38 #include "core/frame/DOMWindow.h" |
| 37 #include "core/frame/LocalDOMWindow.h" | 39 #include "core/frame/LocalDOMWindow.h" |
| 38 #include "core/frame/LocalFrame.h" | 40 #include "core/frame/LocalFrame.h" |
| 39 #include "core/frame/Location.h" | 41 #include "core/frame/Location.h" |
| 40 #include "core/frame/Settings.h" | 42 #include "core/frame/Settings.h" |
| 41 #include "core/html/HTMLFrameElementBase.h" | 43 #include "core/html/HTMLFrameElementBase.h" |
| 42 #include "core/workers/MainThreadWorkletGlobalScope.h" | 44 #include "core/workers/MainThreadWorkletGlobalScope.h" |
| 43 #include "platform/bindings/WrapperCreationSecurityCheck.h" | 45 #include "platform/bindings/WrapperCreationSecurityCheck.h" |
| 44 #include "platform/weborigin/SecurityOrigin.h" | 46 #include "platform/weborigin/SecurityOrigin.h" |
| 45 | 47 |
| 46 namespace blink { | 48 namespace blink { |
| 47 | 49 |
| 48 namespace { | 50 namespace { |
| 49 | 51 |
| 50 bool CanAccessFrameInternal(const LocalDOMWindow* accessing_window, | 52 bool CanAccessWindowInternal(const LocalDOMWindow* accessing_window, |
| 51 const SecurityOrigin* target_frame_origin, | 53 const DOMWindow* target_window) { |
| 52 const DOMWindow* target_window) { | |
| 53 SECURITY_CHECK(!(target_window && target_window->GetFrame()) || | 54 SECURITY_CHECK(!(target_window && target_window->GetFrame()) || |
| 54 target_window == target_window->GetFrame()->DomWindow()); | 55 target_window == target_window->GetFrame()->DomWindow()); |
| 55 | 56 |
| 56 // It's important to check that target_window is a LocalDOMWindow: it's | 57 // It's important to check that target_window is a LocalDOMWindow: it's |
| 57 // possible for a remote frame and local frame to have the same security | 58 // possible for a remote frame and local frame to have the same security |
| 58 // origin, depending on the model being used to allocate Frames between | 59 // origin, depending on the model being used to allocate Frames between |
| 59 // processes. See https://crbug.com/601629. | 60 // processes. See https://crbug.com/601629. |
| 60 if (!(accessing_window && target_window && target_window->IsLocalDOMWindow())) | 61 if (!(accessing_window && target_window && target_window->IsLocalDOMWindow())) |
| 61 return false; | 62 return false; |
| 62 | 63 |
| 63 const SecurityOrigin* accessing_origin = | 64 const SecurityOrigin* accessing_origin = |
| 64 accessing_window->document()->GetSecurityOrigin(); | 65 accessing_window->document()->GetSecurityOrigin(); |
| 65 if (!accessing_origin->CanAccess(target_frame_origin)) | 66 const LocalDOMWindow* local_target_window = ToLocalDOMWindow(target_window); |
| 67 if (!accessing_origin->CanAccess( |
| 68 local_target_window->document()->GetSecurityOrigin())) { |
| 66 return false; | 69 return false; |
| 70 } |
| 67 | 71 |
| 68 // Notify the loader's client if the initial document has been accessed. | 72 // Notify the loader's client if the initial document has been accessed. |
| 69 LocalFrame* target_frame = ToLocalDOMWindow(target_window)->GetFrame(); | 73 LocalFrame* target_frame = local_target_window->GetFrame(); |
| 70 if (target_frame && | 74 if (target_frame && |
| 71 target_frame->Loader().StateMachine()->IsDisplayingInitialEmptyDocument()) | 75 target_frame->Loader().StateMachine()->IsDisplayingInitialEmptyDocument()) |
| 72 target_frame->Loader().DidAccessInitialDocument(); | 76 target_frame->Loader().DidAccessInitialDocument(); |
| 73 | 77 |
| 74 return true; | 78 return true; |
| 75 } | 79 } |
| 76 | 80 |
| 77 bool CanAccessFrame(const LocalDOMWindow* accessing_window, | 81 bool CanAccessWindow(const LocalDOMWindow* accessing_window, |
| 78 const SecurityOrigin* target_frame_origin, | 82 const DOMWindow* target_window, |
| 79 const DOMWindow* target_window, | 83 ExceptionState& exception_state) { |
| 80 ExceptionState& exception_state) { | 84 if (CanAccessWindowInternal(accessing_window, target_window)) |
| 81 if (CanAccessFrameInternal(accessing_window, target_frame_origin, | |
| 82 target_window)) | |
| 83 return true; | 85 return true; |
| 84 | 86 |
| 85 if (target_window) | 87 if (target_window) |
| 86 exception_state.ThrowSecurityError( | 88 exception_state.ThrowSecurityError( |
| 87 target_window->SanitizedCrossDomainAccessErrorMessage(accessing_window), | 89 target_window->SanitizedCrossDomainAccessErrorMessage(accessing_window), |
| 88 target_window->CrossDomainAccessErrorMessage(accessing_window)); | 90 target_window->CrossDomainAccessErrorMessage(accessing_window)); |
| 89 return false; | 91 return false; |
| 90 } | 92 } |
| 91 | 93 |
| 92 bool CanAccessFrame(const LocalDOMWindow* accessing_window, | 94 bool CanAccessWindow(const LocalDOMWindow* accessing_window, |
| 93 SecurityOrigin* target_frame_origin, | 95 const DOMWindow* target_window, |
| 94 const DOMWindow* target_window, | 96 BindingSecurity::ErrorReportOption reporting_option) { |
| 95 BindingSecurity::ErrorReportOption reporting_option) { | 97 if (CanAccessWindowInternal(accessing_window, target_window)) |
| 96 if (CanAccessFrameInternal(accessing_window, target_frame_origin, | |
| 97 target_window)) | |
| 98 return true; | 98 return true; |
| 99 | 99 |
| 100 if (accessing_window && target_window && | 100 if (accessing_window && target_window && |
| 101 reporting_option == BindingSecurity::ErrorReportOption::kReport) | 101 reporting_option == BindingSecurity::ErrorReportOption::kReport) |
| 102 accessing_window->PrintErrorMessage( | 102 accessing_window->PrintErrorMessage( |
| 103 target_window->CrossDomainAccessErrorMessage(accessing_window)); | 103 target_window->CrossDomainAccessErrorMessage(accessing_window)); |
| 104 return false; | 104 return false; |
| 105 } | 105 } |
| 106 | 106 |
| 107 DOMWindow* FindWindow(v8::Isolate* isolate, |
| 108 const WrapperTypeInfo* type, |
| 109 v8::Local<v8::Object> holder) { |
| 110 if (V8Window::wrapperTypeInfo.Equals(type)) |
| 111 return V8Window::toImpl(holder); |
| 112 |
| 113 if (V8Location::wrapperTypeInfo.Equals(type)) |
| 114 return V8Location::toImpl(holder)->DomWindow(); |
| 115 |
| 116 // This function can handle only those types listed above. |
| 117 NOTREACHED(); |
| 118 return nullptr; |
| 119 } |
| 120 |
| 107 } // namespace | 121 } // namespace |
| 108 | 122 |
| 109 bool BindingSecurity::ShouldAllowAccessTo( | 123 bool BindingSecurity::ShouldAllowAccessTo( |
| 110 const LocalDOMWindow* accessing_window, | 124 const LocalDOMWindow* accessing_window, |
| 111 const DOMWindow* target, | 125 const DOMWindow* target, |
| 112 ExceptionState& exception_state) { | 126 ExceptionState& exception_state) { |
| 113 DCHECK(target); | 127 DCHECK(target); |
| 114 const Frame* frame = target->GetFrame(); | 128 |
| 115 if (!frame || !frame->GetSecurityContext()) | 129 // TODO(https://crbug.com/723057): This is intended to match the legacy |
| 130 // behavior of when access checks revolved around Frame pointers rather than |
| 131 // DOMWindow pointers. This prevents web-visible behavior changes, since the |
| 132 // previous implementation had to follow the back pointer to the Frame, and |
| 133 // would have to early return when it was null. |
| 134 if (!target->GetFrame()) |
| 116 return false; | 135 return false; |
| 117 return CanAccessFrame(accessing_window, | 136 |
| 118 frame->GetSecurityContext()->GetSecurityOrigin(), | 137 return CanAccessWindow(accessing_window, target, exception_state); |
| 119 target, exception_state); | |
| 120 } | 138 } |
| 121 | 139 |
| 122 bool BindingSecurity::ShouldAllowAccessTo( | 140 bool BindingSecurity::ShouldAllowAccessTo( |
| 123 const LocalDOMWindow* accessing_window, | 141 const LocalDOMWindow* accessing_window, |
| 124 const DOMWindow* target, | 142 const DOMWindow* target, |
| 125 ErrorReportOption reporting_option) { | 143 ErrorReportOption reporting_option) { |
| 126 DCHECK(target); | 144 DCHECK(target); |
| 127 const Frame* frame = target->GetFrame(); | 145 |
| 128 if (!frame || !frame->GetSecurityContext()) | 146 // TODO(https://crbug.com/723057): This is intended to match the legacy |
| 147 // behavior of when access checks revolved around Frame pointers rather than |
| 148 // DOMWindow pointers. This prevents web-visible behavior changes, since the |
| 149 // previous implementation had to follow the back pointer to the Frame, and |
| 150 // would have to early return when it was null. |
| 151 if (!target->GetFrame()) |
| 129 return false; | 152 return false; |
| 130 return CanAccessFrame(accessing_window, | 153 |
| 131 frame->GetSecurityContext()->GetSecurityOrigin(), | 154 return CanAccessWindow(accessing_window, target, reporting_option); |
| 132 target, reporting_option); | |
| 133 } | 155 } |
| 134 | 156 |
| 135 bool BindingSecurity::ShouldAllowAccessTo( | 157 bool BindingSecurity::ShouldAllowAccessTo( |
| 136 const LocalDOMWindow* accessing_window, | |
| 137 const EventTarget* target, | |
| 138 ExceptionState& exception_state) { | |
| 139 DCHECK(target); | |
| 140 const DOMWindow* window = target->ToDOMWindow(); | |
| 141 if (!window) { | |
| 142 // We only need to check the access to Window objects which are | |
| 143 // cross-origin accessible. If it's not a Window, the object's | |
| 144 // origin must always be the same origin (or it already leaked). | |
| 145 return true; | |
| 146 } | |
| 147 const Frame* frame = window->GetFrame(); | |
| 148 if (!frame || !frame->GetSecurityContext()) | |
| 149 return false; | |
| 150 return CanAccessFrame(accessing_window, | |
| 151 frame->GetSecurityContext()->GetSecurityOrigin(), | |
| 152 window, exception_state); | |
| 153 } | |
| 154 | |
| 155 bool BindingSecurity::ShouldAllowAccessTo( | |
| 156 const LocalDOMWindow* accessing_window, | 158 const LocalDOMWindow* accessing_window, |
| 157 const Location* target, | 159 const Location* target, |
| 158 ExceptionState& exception_state) { | 160 ExceptionState& exception_state) { |
| 159 DCHECK(target); | 161 DCHECK(target); |
| 160 const Frame* frame = target->GetFrame(); | 162 |
| 161 if (!frame || !frame->GetSecurityContext()) | 163 // TODO(https://crbug.com/723057): This is intended to match the legacy |
| 164 // behavior of when access checks revolved around Frame pointers rather than |
| 165 // DOMWindow pointers. This prevents web-visible behavior changes, since the |
| 166 // previous implementation had to follow the back pointer to the Frame, and |
| 167 // would have to early return when it was null. |
| 168 if (!target->DomWindow()->GetFrame()) |
| 162 return false; | 169 return false; |
| 163 return CanAccessFrame(accessing_window, | 170 |
| 164 frame->GetSecurityContext()->GetSecurityOrigin(), | 171 return CanAccessWindow(accessing_window, target->DomWindow(), |
| 165 frame->DomWindow(), exception_state); | 172 exception_state); |
| 166 } | 173 } |
| 167 | 174 |
| 168 bool BindingSecurity::ShouldAllowAccessTo( | 175 bool BindingSecurity::ShouldAllowAccessTo( |
| 169 const LocalDOMWindow* accessing_window, | 176 const LocalDOMWindow* accessing_window, |
| 170 const Location* target, | 177 const Location* target, |
| 171 ErrorReportOption reporting_option) { | 178 ErrorReportOption reporting_option) { |
| 172 DCHECK(target); | 179 DCHECK(target); |
| 173 const Frame* frame = target->GetFrame(); | 180 |
| 174 if (!frame || !frame->GetSecurityContext()) | 181 // TODO(https://crbug.com/723057): This is intended to match the legacy |
| 182 // behavior of when access checks revolved around Frame pointers rather than |
| 183 // DOMWindow pointers. This prevents web-visible behavior changes, since the |
| 184 // previous implementation had to follow the back pointer to the Frame, and |
| 185 // would have to early return when it was null. |
| 186 if (!target->DomWindow()->GetFrame()) |
| 175 return false; | 187 return false; |
| 176 return CanAccessFrame(accessing_window, | 188 |
| 177 frame->GetSecurityContext()->GetSecurityOrigin(), | 189 return CanAccessWindow(accessing_window, target->DomWindow(), |
| 178 frame->DomWindow(), reporting_option); | 190 reporting_option); |
| 179 } | 191 } |
| 180 | 192 |
| 181 bool BindingSecurity::ShouldAllowAccessTo( | 193 bool BindingSecurity::ShouldAllowAccessTo( |
| 182 const LocalDOMWindow* accessing_window, | 194 const LocalDOMWindow* accessing_window, |
| 183 const Node* target, | 195 const Node* target, |
| 184 ExceptionState& exception_state) { | 196 ExceptionState& exception_state) { |
| 185 if (!target) | 197 if (!target) |
| 186 return false; | 198 return false; |
| 187 return CanAccessFrame(accessing_window, | 199 return CanAccessWindow(accessing_window, target->GetDocument().domWindow(), |
| 188 target->GetDocument().GetSecurityOrigin(), | 200 exception_state); |
| 189 target->GetDocument().domWindow(), exception_state); | |
| 190 } | 201 } |
| 191 | 202 |
| 192 bool BindingSecurity::ShouldAllowAccessTo( | 203 bool BindingSecurity::ShouldAllowAccessTo( |
| 193 const LocalDOMWindow* accessing_window, | 204 const LocalDOMWindow* accessing_window, |
| 194 const Node* target, | 205 const Node* target, |
| 195 ErrorReportOption reporting_option) { | 206 ErrorReportOption reporting_option) { |
| 196 if (!target) | 207 if (!target) |
| 197 return false; | 208 return false; |
| 198 return CanAccessFrame(accessing_window, | 209 return CanAccessWindow(accessing_window, target->GetDocument().domWindow(), |
| 199 target->GetDocument().GetSecurityOrigin(), | 210 reporting_option); |
| 200 target->GetDocument().domWindow(), reporting_option); | |
| 201 } | 211 } |
| 202 | 212 |
| 203 bool BindingSecurity::ShouldAllowAccessToFrame( | 213 bool BindingSecurity::ShouldAllowAccessToFrame( |
| 204 const LocalDOMWindow* accessing_window, | 214 const LocalDOMWindow* accessing_window, |
| 205 const Frame* target, | 215 const Frame* target, |
| 206 ExceptionState& exception_state) { | 216 ExceptionState& exception_state) { |
| 207 if (!target || !target->GetSecurityContext()) | 217 if (!target || !target->GetSecurityContext()) |
| 208 return false; | 218 return false; |
| 209 return CanAccessFrame(accessing_window, | 219 return CanAccessWindow(accessing_window, target->DomWindow(), |
| 210 target->GetSecurityContext()->GetSecurityOrigin(), | 220 exception_state); |
| 211 target->DomWindow(), exception_state); | |
| 212 } | 221 } |
| 213 | 222 |
| 214 bool BindingSecurity::ShouldAllowAccessToFrame( | 223 bool BindingSecurity::ShouldAllowAccessToFrame( |
| 215 const LocalDOMWindow* accessing_window, | 224 const LocalDOMWindow* accessing_window, |
| 216 const Frame* target, | 225 const Frame* target, |
| 217 ErrorReportOption reporting_option) { | 226 ErrorReportOption reporting_option) { |
| 218 if (!target || !target->GetSecurityContext()) | 227 if (!target || !target->GetSecurityContext()) |
| 219 return false; | 228 return false; |
| 220 return CanAccessFrame(accessing_window, | 229 return CanAccessWindow(accessing_window, target->DomWindow(), |
| 221 target->GetSecurityContext()->GetSecurityOrigin(), | 230 reporting_option); |
| 222 target->DomWindow(), reporting_option); | |
| 223 } | |
| 224 | |
| 225 bool BindingSecurity::ShouldAllowAccessToDetachedWindow( | |
| 226 const LocalDOMWindow* accessing_window, | |
| 227 const DOMWindow* target, | |
| 228 ExceptionState& exception_state) { | |
| 229 CHECK(target && !target->GetFrame()) | |
| 230 << "This version of shouldAllowAccessToFrame() must be used only for " | |
| 231 << "detached windows."; | |
| 232 if (!target->IsLocalDOMWindow()) | |
| 233 return false; | |
| 234 Document* document = ToLocalDOMWindow(target)->document(); | |
| 235 if (!document) | |
| 236 return false; | |
| 237 return CanAccessFrame(accessing_window, document->GetSecurityOrigin(), target, | |
| 238 exception_state); | |
| 239 } | 231 } |
| 240 | 232 |
| 241 bool BindingSecurity::ShouldAllowNamedAccessTo( | 233 bool BindingSecurity::ShouldAllowNamedAccessTo( |
| 242 const DOMWindow* accessing_window, | 234 const DOMWindow* accessing_window, |
| 243 const DOMWindow* target_window) { | 235 const DOMWindow* target_window) { |
| 244 const Frame* accessing_frame = accessing_window->GetFrame(); | 236 const Frame* accessing_frame = accessing_window->GetFrame(); |
| 245 DCHECK(accessing_frame); | 237 DCHECK(accessing_frame); |
| 246 DCHECK(accessing_frame->GetSecurityContext()); | 238 DCHECK(accessing_frame->GetSecurityContext()); |
| 247 const SecurityOrigin* accessing_origin = | 239 const SecurityOrigin* accessing_origin = |
| 248 accessing_frame->GetSecurityContext()->GetSecurityOrigin(); | 240 accessing_frame->GetSecurityContext()->GetSecurityOrigin(); |
| (...skipping 24 matching lines...) Expand all Loading... |
| 273 // https://html.spec.whatwg.org/multipage/browsers.html#security-location, | 265 // https://html.spec.whatwg.org/multipage/browsers.html#security-location, |
| 274 // cross-origin script access to a few properties of Location is allowed. | 266 // cross-origin script access to a few properties of Location is allowed. |
| 275 // Location already implements the necessary security checks. | 267 // Location already implements the necessary security checks. |
| 276 if (type->Equals(&V8Location::wrapperTypeInfo)) | 268 if (type->Equals(&V8Location::wrapperTypeInfo)) |
| 277 return true; | 269 return true; |
| 278 | 270 |
| 279 v8::Isolate* isolate = creation_context->GetIsolate(); | 271 v8::Isolate* isolate = creation_context->GetIsolate(); |
| 280 LocalFrame* frame = ToLocalFrameIfNotDetached(creation_context); | 272 LocalFrame* frame = ToLocalFrameIfNotDetached(creation_context); |
| 281 ExceptionState exception_state(isolate, ExceptionState::kConstructionContext, | 273 ExceptionState exception_state(isolate, ExceptionState::kConstructionContext, |
| 282 type->interface_name); | 274 type->interface_name); |
| 275 // TODO(dcheng): Why doesn't this code just use DOMWindows throughout? Can't |
| 276 // we just always use ToLocalDOMWindow(creation_context)? |
| 283 if (!frame) { | 277 if (!frame) { |
| 284 // Sandbox detached frames - they can't create cross origin objects. | 278 // Sandbox detached frames - they can't create cross origin objects. |
| 285 LocalDOMWindow* calling_window = CurrentDOMWindow(isolate); | 279 LocalDOMWindow* calling_window = CurrentDOMWindow(isolate); |
| 286 LocalDOMWindow* target_window = ToLocalDOMWindow(creation_context); | 280 LocalDOMWindow* target_window = ToLocalDOMWindow(creation_context); |
| 287 | 281 |
| 288 return ShouldAllowAccessToDetachedWindow(calling_window, target_window, | 282 // TODO(https://crbug.com/723057): This is tricky: this intentionally uses |
| 289 exception_state); | 283 // the internal CanAccessWindow() helper rather than ShouldAllowAccessTo(). |
| 284 // ShouldAllowAccessTo() unconditionally denies access if the DOMWindow is |
| 285 // not attached to a Frame, but this code is intended for handling the |
| 286 // detached DOMWindow case. |
| 287 return CanAccessWindow(calling_window, target_window, exception_state); |
| 290 } | 288 } |
| 291 const DOMWrapperWorld& current_world = | 289 const DOMWrapperWorld& current_world = |
| 292 DOMWrapperWorld::World(isolate->GetCurrentContext()); | 290 DOMWrapperWorld::World(isolate->GetCurrentContext()); |
| 293 CHECK_EQ(current_world.GetWorldId(), | 291 CHECK_EQ(current_world.GetWorldId(), |
| 294 DOMWrapperWorld::World(creation_context).GetWorldId()); | 292 DOMWrapperWorld::World(creation_context).GetWorldId()); |
| 295 | 293 |
| 296 return !current_world.IsMainWorld() || | 294 return !current_world.IsMainWorld() || |
| 297 ShouldAllowAccessToFrame(CurrentDOMWindow(isolate), frame, | 295 ShouldAllowAccessToFrame(CurrentDOMWindow(isolate), frame, |
| 298 exception_state); | 296 exception_state); |
| 299 } | 297 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 319 } | 317 } |
| 320 | 318 |
| 321 void BindingSecurity::InitWrapperCreationSecurityCheck() { | 319 void BindingSecurity::InitWrapperCreationSecurityCheck() { |
| 322 WrapperCreationSecurityCheck::SetSecurityCheckFunction( | 320 WrapperCreationSecurityCheck::SetSecurityCheckFunction( |
| 323 &ShouldAllowAccessToCreationContext); | 321 &ShouldAllowAccessToCreationContext); |
| 324 WrapperCreationSecurityCheck::SetRethrowExceptionFunction( | 322 WrapperCreationSecurityCheck::SetRethrowExceptionFunction( |
| 325 &RethrowCrossContextException); | 323 &RethrowCrossContextException); |
| 326 } | 324 } |
| 327 | 325 |
| 328 void BindingSecurity::FailedAccessCheckFor(v8::Isolate* isolate, | 326 void BindingSecurity::FailedAccessCheckFor(v8::Isolate* isolate, |
| 329 const Frame* target) { | 327 const WrapperTypeInfo* type, |
| 330 // TODO(dcheng): See if this null check can be removed or hoisted to a | 328 v8::Local<v8::Object> holder) { |
| 331 // different location. | 329 DOMWindow* target = FindWindow(isolate, type, holder); |
| 332 if (!target) | 330 // Failing to find a target means something is wrong. Failing to throw an |
| 331 // exception could be a security issue, so just crash. |
| 332 CHECK(target); |
| 333 |
| 334 // TODO(https://crbug.com/723057): This is intended to match the legacy |
| 335 // behavior of when access checks revolved around Frame pointers rather than |
| 336 // DOMWindow pointers. This prevents web-visible behavior changes, since the |
| 337 // previous implementation had to follow the back pointer to the Frame, and |
| 338 // would have to early return when it was null. |
| 339 if (!target->GetFrame()) |
| 333 return; | 340 return; |
| 334 | 341 |
| 335 DOMWindow* target_window = target->DomWindow(); | |
| 336 | |
| 337 // TODO(dcheng): Add ContextType, interface name, and property name as | 342 // TODO(dcheng): Add ContextType, interface name, and property name as |
| 338 // arguments, so the generated exception can be more descriptive. | 343 // arguments, so the generated exception can be more descriptive. |
| 339 ExceptionState exception_state(isolate, ExceptionState::kUnknownContext, | 344 ExceptionState exception_state(isolate, ExceptionState::kUnknownContext, |
| 340 nullptr, nullptr); | 345 nullptr, nullptr); |
| 341 exception_state.ThrowSecurityError( | 346 exception_state.ThrowSecurityError( |
| 342 target_window->SanitizedCrossDomainAccessErrorMessage( | 347 target->SanitizedCrossDomainAccessErrorMessage(CurrentDOMWindow(isolate)), |
| 343 CurrentDOMWindow(isolate)), | 348 target->CrossDomainAccessErrorMessage(CurrentDOMWindow(isolate))); |
| 344 target_window->CrossDomainAccessErrorMessage(CurrentDOMWindow(isolate))); | |
| 345 } | 349 } |
| 346 | 350 |
| 347 } // namespace blink | 351 } // namespace blink |
| OLD | NEW |