| 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" |
| 35 #include "core/dom/Document.h" | 37 #include "core/dom/Document.h" |
| 36 #include "core/frame/LocalDOMWindow.h" | 38 #include "core/frame/LocalDOMWindow.h" |
| 37 #include "core/frame/LocalFrame.h" | 39 #include "core/frame/LocalFrame.h" |
| 38 #include "core/frame/Location.h" | 40 #include "core/frame/Location.h" |
| 39 #include "core/frame/Settings.h" | 41 #include "core/frame/Settings.h" |
| 40 #include "core/html/HTMLFrameElementBase.h" | 42 #include "core/html/HTMLFrameElementBase.h" |
| 41 #include "core/workers/MainThreadWorkletGlobalScope.h" | 43 #include "core/workers/MainThreadWorkletGlobalScope.h" |
| 42 #include "platform/weborigin/SecurityOrigin.h" | 44 #include "platform/weborigin/SecurityOrigin.h" |
| 43 | 45 |
| 44 namespace blink { | 46 namespace blink { |
| 45 | 47 |
| 46 namespace { | 48 namespace { |
| 47 | 49 |
| 48 bool CanAccessFrameInternal(const LocalDOMWindow* accessing_window, | 50 bool CanAccessFrameInternal(const LocalDOMWindow* accessing_window, |
| 49 const SecurityOrigin* target_frame_origin, | 51 const SecurityOrigin* target_frame_origin, |
| 50 const DOMWindow* target_window) { | 52 const DOMWindow* target_window) { |
| 51 SECURITY_CHECK(!(target_window && target_window->GetFrame()) || | 53 SECURITY_CHECK(!(target_window && target_window->GetFrame()) || |
| 52 target_window == target_window->GetFrame()->DomWindow()); | 54 target_window == target_window->GetFrame()->DomWindow()); |
| 53 | 55 |
| 54 // It's important to check that targetWindow is a LocalDOMWindow: it's | 56 // It's important to check that target_window is a LocalDOMWindow: it's |
| 55 // possible for a remote frame and local frame to have the same security | 57 // 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 | 58 // origin, depending on the model being used to allocate Frames between |
| 57 // processes. See https://crbug.com/601629. | 59 // processes. See https://crbug.com/601629. |
| 58 if (!(accessing_window && target_window && target_window->IsLocalDOMWindow())) | 60 if (!(accessing_window && target_window && target_window->IsLocalDOMWindow())) |
| 59 return false; | 61 return false; |
| 60 | 62 |
| 61 const SecurityOrigin* accessing_origin = | 63 const SecurityOrigin* accessing_origin = |
| 62 accessing_window->document()->GetSecurityOrigin(); | 64 accessing_window->document()->GetSecurityOrigin(); |
| 63 if (!accessing_origin->CanAccess(target_frame_origin)) | 65 if (!accessing_origin->CanAccess(target_frame_origin)) |
| 64 return false; | 66 return false; |
| (...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 return false; | 259 return false; |
| 258 | 260 |
| 259 // Note that there is no need to call back | 261 // Note that there is no need to call back |
| 260 // FrameLoader::didAccessInitialDocument() because |targetWindow| must be | 262 // FrameLoader::didAccessInitialDocument() because |targetWindow| must be |
| 261 // a child window inside iframe or frame and it doesn't have a URL bar, | 263 // a child window inside iframe or frame and it doesn't have a URL bar, |
| 262 // so there is no need to worry about URL spoofing. | 264 // so there is no need to worry about URL spoofing. |
| 263 | 265 |
| 264 return true; | 266 return true; |
| 265 } | 267 } |
| 266 | 268 |
| 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 |
| 267 void BindingSecurity::FailedAccessCheckFor(v8::Isolate* isolate, | 328 void BindingSecurity::FailedAccessCheckFor(v8::Isolate* isolate, |
| 268 const Frame* target) { | 329 const Frame* target) { |
| 269 // TODO(dcheng): See if this null check can be removed or hoisted to a | 330 // TODO(dcheng): See if this null check can be removed or hoisted to a |
| 270 // different location. | 331 // different location. |
| 271 if (!target) | 332 if (!target) |
| 272 return; | 333 return; |
| 273 | 334 |
| 274 DOMWindow* target_window = target->DomWindow(); | 335 DOMWindow* target_window = target->DomWindow(); |
| 275 | 336 |
| 276 // TODO(dcheng): Add ContextType, interface name, and property name as | 337 // TODO(dcheng): Add ContextType, interface name, and property name as |
| 277 // arguments, so the generated exception can be more descriptive. | 338 // arguments, so the generated exception can be more descriptive. |
| 278 ExceptionState exception_state(isolate, ExceptionState::kUnknownContext, | 339 ExceptionState exception_state(isolate, ExceptionState::kUnknownContext, |
| 279 nullptr, nullptr); | 340 nullptr, nullptr); |
| 280 exception_state.ThrowSecurityError( | 341 exception_state.ThrowSecurityError( |
| 281 target_window->SanitizedCrossDomainAccessErrorMessage( | 342 target_window->SanitizedCrossDomainAccessErrorMessage( |
| 282 CurrentDOMWindow(isolate)), | 343 CurrentDOMWindow(isolate)), |
| 283 target_window->CrossDomainAccessErrorMessage(CurrentDOMWindow(isolate))); | 344 target_window->CrossDomainAccessErrorMessage(CurrentDOMWindow(isolate))); |
| 284 } | 345 } |
| 285 | 346 |
| 286 } // namespace blink | 347 } // namespace blink |
| OLD | NEW |