| 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 14 matching lines...) Expand all Loading... |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 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/V8Binding.h" | 34 #include "bindings/core/v8/V8Binding.h" |
| 35 #include "bindings/core/v8/V8Location.h" | |
| 36 #include "bindings/core/v8/WrapperCreationSecurityCheck.h" | |
| 37 #include "core/dom/Document.h" | 35 #include "core/dom/Document.h" |
| 38 #include "core/frame/LocalDOMWindow.h" | 36 #include "core/frame/LocalDOMWindow.h" |
| 39 #include "core/frame/LocalFrame.h" | 37 #include "core/frame/LocalFrame.h" |
| 40 #include "core/frame/Location.h" | 38 #include "core/frame/Location.h" |
| 41 #include "core/frame/Settings.h" | 39 #include "core/frame/Settings.h" |
| 42 #include "core/html/HTMLFrameElementBase.h" | 40 #include "core/html/HTMLFrameElementBase.h" |
| 43 #include "core/workers/MainThreadWorkletGlobalScope.h" | 41 #include "core/workers/MainThreadWorkletGlobalScope.h" |
| 44 #include "platform/weborigin/SecurityOrigin.h" | 42 #include "platform/weborigin/SecurityOrigin.h" |
| 45 | 43 |
| 46 namespace blink { | 44 namespace blink { |
| 47 | 45 |
| 48 namespace { | 46 namespace { |
| 49 | 47 |
| 50 bool CanAccessFrameInternal(const LocalDOMWindow* accessing_window, | 48 bool CanAccessFrameInternal(const LocalDOMWindow* accessing_window, |
| 51 const SecurityOrigin* target_frame_origin, | 49 const SecurityOrigin* target_frame_origin, |
| 52 const DOMWindow* target_window) { | 50 const DOMWindow* target_window) { |
| 53 SECURITY_CHECK(!(target_window && target_window->GetFrame()) || | 51 SECURITY_CHECK(!(target_window && target_window->GetFrame()) || |
| 54 target_window == target_window->GetFrame()->DomWindow()); | 52 target_window == target_window->GetFrame()->DomWindow()); |
| 55 | 53 |
| 56 // It's important to check that target_window is a LocalDOMWindow: it's | 54 // It's important to check that targetWindow is a LocalDOMWindow: it's |
| 57 // possible for a remote frame and local frame to have the same security | 55 // 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 | 56 // origin, depending on the model being used to allocate Frames between |
| 59 // processes. See https://crbug.com/601629. | 57 // processes. See https://crbug.com/601629. |
| 60 if (!(accessing_window && target_window && target_window->IsLocalDOMWindow())) | 58 if (!(accessing_window && target_window && target_window->IsLocalDOMWindow())) |
| 61 return false; | 59 return false; |
| 62 | 60 |
| 63 const SecurityOrigin* accessing_origin = | 61 const SecurityOrigin* accessing_origin = |
| 64 accessing_window->document()->GetSecurityOrigin(); | 62 accessing_window->document()->GetSecurityOrigin(); |
| 65 if (!accessing_origin->CanAccess(target_frame_origin)) | 63 if (!accessing_origin->CanAccess(target_frame_origin)) |
| 66 return false; | 64 return false; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 return false; | 257 return false; |
| 260 | 258 |
| 261 // Note that there is no need to call back | 259 // Note that there is no need to call back |
| 262 // FrameLoader::didAccessInitialDocument() because |targetWindow| must be | 260 // FrameLoader::didAccessInitialDocument() because |targetWindow| must be |
| 263 // a child window inside iframe or frame and it doesn't have a URL bar, | 261 // a child window inside iframe or frame and it doesn't have a URL bar, |
| 264 // so there is no need to worry about URL spoofing. | 262 // so there is no need to worry about URL spoofing. |
| 265 | 263 |
| 266 return true; | 264 return true; |
| 267 } | 265 } |
| 268 | 266 |
| 269 bool BindingSecurity::ShouldAllowAccessToCreationContext( | |
| 270 v8::Local<v8::Context> creation_context, | |
| 271 const WrapperTypeInfo* type) { | |
| 272 // According to | |
| 273 // https://html.spec.whatwg.org/multipage/browsers.html#security-location, | |
| 274 // cross-origin script access to a few properties of Location is allowed. | |
| 275 // Location already implements the necessary security checks. | |
| 276 if (type->Equals(&V8Location::wrapperTypeInfo)) | |
| 277 return true; | |
| 278 | |
| 279 v8::Isolate* isolate = creation_context->GetIsolate(); | |
| 280 LocalFrame* frame = ToLocalFrameIfNotDetached(creation_context); | |
| 281 ExceptionState exception_state(isolate, ExceptionState::kConstructionContext, | |
| 282 type->interface_name); | |
| 283 if (!frame) { | |
| 284 // Sandbox detached frames - they can't create cross origin objects. | |
| 285 LocalDOMWindow* calling_window = CurrentDOMWindow(isolate); | |
| 286 LocalDOMWindow* target_window = ToLocalDOMWindow(creation_context); | |
| 287 | |
| 288 return ShouldAllowAccessToDetachedWindow(calling_window, target_window, | |
| 289 exception_state); | |
| 290 } | |
| 291 const DOMWrapperWorld& current_world = | |
| 292 DOMWrapperWorld::World(isolate->GetCurrentContext()); | |
| 293 CHECK_EQ(current_world.GetWorldId(), | |
| 294 DOMWrapperWorld::World(creation_context).GetWorldId()); | |
| 295 | |
| 296 return !current_world.IsMainWorld() || | |
| 297 ShouldAllowAccessToFrame(CurrentDOMWindow(isolate), frame, | |
| 298 exception_state); | |
| 299 } | |
| 300 | |
| 301 void BindingSecurity::RethrowCrossContextException( | |
| 302 v8::Local<v8::Context> creation_context, | |
| 303 const WrapperTypeInfo* type, | |
| 304 v8::Local<v8::Value> cross_context_exception) { | |
| 305 DCHECK(!cross_context_exception.IsEmpty()); | |
| 306 v8::Isolate* isolate = creation_context->GetIsolate(); | |
| 307 ExceptionState exception_state(isolate, ExceptionState::kConstructionContext, | |
| 308 type->interface_name); | |
| 309 if (type->Equals(&V8Location::wrapperTypeInfo)) { | |
| 310 // Convert cross-context exception to security error | |
| 311 LocalDOMWindow* calling_window = CurrentDOMWindow(isolate); | |
| 312 LocalDOMWindow* target_window = ToLocalDOMWindow(creation_context); | |
| 313 exception_state.ThrowSecurityError( | |
| 314 target_window->SanitizedCrossDomainAccessErrorMessage(calling_window), | |
| 315 target_window->CrossDomainAccessErrorMessage(calling_window)); | |
| 316 return; | |
| 317 } | |
| 318 exception_state.RethrowV8Exception(cross_context_exception); | |
| 319 } | |
| 320 | |
| 321 void BindingSecurity::InitWrapperCreationSecurityCheck() { | |
| 322 WrapperCreationSecurityCheck::SetSecurityCheckFunction( | |
| 323 &ShouldAllowAccessToCreationContext); | |
| 324 WrapperCreationSecurityCheck::SetRethrowExceptionFunction( | |
| 325 &RethrowCrossContextException); | |
| 326 } | |
| 327 | |
| 328 void BindingSecurity::FailedAccessCheckFor(v8::Isolate* isolate, | 267 void BindingSecurity::FailedAccessCheckFor(v8::Isolate* isolate, |
| 329 const Frame* target) { | 268 const Frame* target) { |
| 330 // TODO(dcheng): See if this null check can be removed or hoisted to a | 269 // TODO(dcheng): See if this null check can be removed or hoisted to a |
| 331 // different location. | 270 // different location. |
| 332 if (!target) | 271 if (!target) |
| 333 return; | 272 return; |
| 334 | 273 |
| 335 DOMWindow* target_window = target->DomWindow(); | 274 DOMWindow* target_window = target->DomWindow(); |
| 336 | 275 |
| 337 // TODO(dcheng): Add ContextType, interface name, and property name as | 276 // TODO(dcheng): Add ContextType, interface name, and property name as |
| 338 // arguments, so the generated exception can be more descriptive. | 277 // arguments, so the generated exception can be more descriptive. |
| 339 ExceptionState exception_state(isolate, ExceptionState::kUnknownContext, | 278 ExceptionState exception_state(isolate, ExceptionState::kUnknownContext, |
| 340 nullptr, nullptr); | 279 nullptr, nullptr); |
| 341 exception_state.ThrowSecurityError( | 280 exception_state.ThrowSecurityError( |
| 342 target_window->SanitizedCrossDomainAccessErrorMessage( | 281 target_window->SanitizedCrossDomainAccessErrorMessage( |
| 343 CurrentDOMWindow(isolate)), | 282 CurrentDOMWindow(isolate)), |
| 344 target_window->CrossDomainAccessErrorMessage(CurrentDOMWindow(isolate))); | 283 target_window->CrossDomainAccessErrorMessage(CurrentDOMWindow(isolate))); |
| 345 } | 284 } |
| 346 | 285 |
| 347 } // namespace blink | 286 } // namespace blink |
| OLD | NEW |