| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "core/frame/DOMWindow.h" | 5 #include "core/frame/DOMWindow.h" |
| 6 | 6 |
| 7 #include "core/dom/Document.h" | 7 #include "core/dom/Document.h" |
| 8 #include "core/dom/ExceptionCode.h" | 8 #include "core/dom/ExceptionCode.h" |
| 9 #include "core/dom/ExecutionContext.h" | 9 #include "core/dom/ExecutionContext.h" |
| 10 #include "core/dom/SecurityContext.h" | 10 #include "core/dom/SecurityContext.h" |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 127 } | 127 } |
| 128 | 128 |
| 129 bool DOMWindow::isInsecureScriptAccess(LocalDOMWindow& callingWindow, | 129 bool DOMWindow::isInsecureScriptAccess(LocalDOMWindow& callingWindow, |
| 130 const String& urlString) { | 130 const String& urlString) { |
| 131 if (!protocolIsJavaScript(urlString)) | 131 if (!protocolIsJavaScript(urlString)) |
| 132 return false; | 132 return false; |
| 133 | 133 |
| 134 // If this DOMWindow isn't currently active in the Frame, then there's no | 134 // If this DOMWindow isn't currently active in the Frame, then there's no |
| 135 // way we should allow the access. | 135 // way we should allow the access. |
| 136 if (isCurrentlyDisplayedInFrame()) { | 136 if (isCurrentlyDisplayedInFrame()) { |
| 137 // FIXME: Is there some way to eliminate the need for a separate "callingWin
dow == this" check? | 137 // FIXME: Is there some way to eliminate the need for a separate |
| 138 // "callingWindow == this" check? |
| 138 if (&callingWindow == this) | 139 if (&callingWindow == this) |
| 139 return false; | 140 return false; |
| 140 | 141 |
| 141 // FIXME: The name canAccess seems to be a roundabout way to ask "can execut
e script". | 142 // FIXME: The name canAccess seems to be a roundabout way to ask "can |
| 142 // Can we name the SecurityOrigin function better to make this more clear? | 143 // execute script". Can we name the SecurityOrigin function better to make |
| 144 // this more clear? |
| 143 if (callingWindow.document()->getSecurityOrigin()->canAccessCheckSuborigins( | 145 if (callingWindow.document()->getSecurityOrigin()->canAccessCheckSuborigins( |
| 144 frame()->securityContext()->getSecurityOrigin())) | 146 frame()->securityContext()->getSecurityOrigin())) |
| 145 return false; | 147 return false; |
| 146 } | 148 } |
| 147 | 149 |
| 148 callingWindow.printErrorMessage( | 150 callingWindow.printErrorMessage( |
| 149 crossDomainAccessErrorMessage(&callingWindow)); | 151 crossDomainAccessErrorMessage(&callingWindow)); |
| 150 return true; | 152 return true; |
| 151 } | 153 } |
| 152 | 154 |
| 153 void DOMWindow::resetLocation() { | 155 void DOMWindow::resetLocation() { |
| 154 // Location needs to be reset manually because it doesn't inherit from DOMWind
owProperty. | 156 // Location needs to be reset manually because it doesn't inherit from |
| 155 // DOMWindowProperty is local-only, and Location needs to support remote windo
ws, too. | 157 // DOMWindowProperty. DOMWindowProperty is local-only, and Location needs to |
| 158 // support remote windows, too. |
| 156 if (m_location) { | 159 if (m_location) { |
| 157 m_location->reset(); | 160 m_location->reset(); |
| 158 m_location = nullptr; | 161 m_location = nullptr; |
| 159 } | 162 } |
| 160 } | 163 } |
| 161 | 164 |
| 162 bool DOMWindow::isSecureContext() const { | 165 bool DOMWindow::isSecureContext() const { |
| 163 if (!frame()) | 166 if (!frame()) |
| 164 return false; | 167 return false; |
| 165 | 168 |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 233 sourceDocument->url())) | 236 sourceDocument->url())) |
| 234 UseCounter::count(frame(), UseCounter::PostMessageFromInsecureToSecure); | 237 UseCounter::count(frame(), UseCounter::PostMessageFromInsecureToSecure); |
| 235 | 238 |
| 236 MessageEvent* event = | 239 MessageEvent* event = |
| 237 MessageEvent::create(std::move(channels), std::move(message), | 240 MessageEvent::create(std::move(channels), std::move(message), |
| 238 sourceOrigin, String(), source, sourceSuborigin); | 241 sourceOrigin, String(), source, sourceSuborigin); |
| 239 | 242 |
| 240 schedulePostMessage(event, std::move(target), sourceDocument); | 243 schedulePostMessage(event, std::move(target), sourceDocument); |
| 241 } | 244 } |
| 242 | 245 |
| 243 // FIXME: Once we're throwing exceptions for cross-origin access violations, we
will always sanitize the target | 246 // FIXME: Once we're throwing exceptions for cross-origin access violations, we |
| 244 // frame details, so we can safely combine 'crossDomainAccessErrorMessage' with
this method after considering | 247 // will always sanitize the target frame details, so we can safely combine |
| 245 // exactly which details may be exposed to JavaScript. | 248 // 'crossDomainAccessErrorMessage' with this method after considering exactly |
| 249 // which details may be exposed to JavaScript. |
| 246 // | 250 // |
| 247 // http://crbug.com/17325 | 251 // http://crbug.com/17325 |
| 248 String DOMWindow::sanitizedCrossDomainAccessErrorMessage( | 252 String DOMWindow::sanitizedCrossDomainAccessErrorMessage( |
| 249 const LocalDOMWindow* callingWindow) const { | 253 const LocalDOMWindow* callingWindow) const { |
| 250 if (!callingWindow || !callingWindow->document() || !frame()) | 254 if (!callingWindow || !callingWindow->document() || !frame()) |
| 251 return String(); | 255 return String(); |
| 252 | 256 |
| 253 const KURL& callingWindowURL = callingWindow->document()->url(); | 257 const KURL& callingWindowURL = callingWindow->document()->url(); |
| 254 if (callingWindowURL.isNull()) | 258 if (callingWindowURL.isNull()) |
| 255 return String(); | 259 return String(); |
| 256 | 260 |
| 257 const SecurityOrigin* activeOrigin = | 261 const SecurityOrigin* activeOrigin = |
| 258 callingWindow->document()->getSecurityOrigin(); | 262 callingWindow->document()->getSecurityOrigin(); |
| 259 String message = "Blocked a frame with origin \"" + activeOrigin->toString() + | 263 String message = "Blocked a frame with origin \"" + activeOrigin->toString() + |
| 260 "\" from accessing a cross-origin frame."; | 264 "\" from accessing a cross-origin frame."; |
| 261 | 265 |
| 262 // FIXME: Evaluate which details from 'crossDomainAccessErrorMessage' may safe
ly be reported to JavaScript. | 266 // FIXME: Evaluate which details from 'crossDomainAccessErrorMessage' may |
| 267 // safely be reported to JavaScript. |
| 263 | 268 |
| 264 return message; | 269 return message; |
| 265 } | 270 } |
| 266 | 271 |
| 267 String DOMWindow::crossDomainAccessErrorMessage( | 272 String DOMWindow::crossDomainAccessErrorMessage( |
| 268 const LocalDOMWindow* callingWindow) const { | 273 const LocalDOMWindow* callingWindow) const { |
| 269 if (!callingWindow || !callingWindow->document() || !frame()) | 274 if (!callingWindow || !callingWindow->document() || !frame()) |
| 270 return String(); | 275 return String(); |
| 271 | 276 |
| 272 const KURL& callingWindowURL = callingWindow->document()->url(); | 277 const KURL& callingWindowURL = callingWindow->document()->url(); |
| 273 if (callingWindowURL.isNull()) | 278 if (callingWindowURL.isNull()) |
| 274 return String(); | 279 return String(); |
| 275 | 280 |
| 276 // FIXME: This message, and other console messages, have extra newlines. Shoul
d remove them. | 281 // FIXME: This message, and other console messages, have extra newlines. |
| 282 // Should remove them. |
| 277 const SecurityOrigin* activeOrigin = | 283 const SecurityOrigin* activeOrigin = |
| 278 callingWindow->document()->getSecurityOrigin(); | 284 callingWindow->document()->getSecurityOrigin(); |
| 279 const SecurityOrigin* targetOrigin = | 285 const SecurityOrigin* targetOrigin = |
| 280 frame()->securityContext()->getSecurityOrigin(); | 286 frame()->securityContext()->getSecurityOrigin(); |
| 281 // It's possible for a remote frame to be same origin with respect to a | 287 // It's possible for a remote frame to be same origin with respect to a |
| 282 // local frame, but it must still be treated as a disallowed cross-domain | 288 // local frame, but it must still be treated as a disallowed cross-domain |
| 283 // access. See https://crbug.com/601629. | 289 // access. See https://crbug.com/601629. |
| 284 ASSERT(frame()->isRemoteFrame() || | 290 ASSERT(frame()->isRemoteFrame() || |
| 285 !activeOrigin->canAccessCheckSuborigins(targetOrigin)); | 291 !activeOrigin->canAccessCheckSuborigins(targetOrigin)); |
| 286 | 292 |
| 287 String message = "Blocked a frame with origin \"" + activeOrigin->toString() + | 293 String message = "Blocked a frame with origin \"" + activeOrigin->toString() + |
| 288 "\" from accessing a frame with origin \"" + | 294 "\" from accessing a frame with origin \"" + |
| 289 targetOrigin->toString() + "\". "; | 295 targetOrigin->toString() + "\". "; |
| 290 | 296 |
| 291 // Sandbox errors: Use the origin of the frames' location, rather than their a
ctual origin (since we know that at least one will be "null"). | 297 // Sandbox errors: Use the origin of the frames' location, rather than their |
| 298 // actual origin (since we know that at least one will be "null"). |
| 292 KURL activeURL = callingWindow->document()->url(); | 299 KURL activeURL = callingWindow->document()->url(); |
| 293 // TODO(alexmos): RemoteFrames do not have a document, and their URLs | 300 // TODO(alexmos): RemoteFrames do not have a document, and their URLs |
| 294 // aren't replicated. For now, construct the URL using the replicated | 301 // aren't replicated. For now, construct the URL using the replicated |
| 295 // origin for RemoteFrames. If the target frame is remote and sandboxed, | 302 // origin for RemoteFrames. If the target frame is remote and sandboxed, |
| 296 // there isn't anything else to show other than "null" for its origin. | 303 // there isn't anything else to show other than "null" for its origin. |
| 297 KURL targetURL = isLocalDOMWindow() ? document()->url() | 304 KURL targetURL = isLocalDOMWindow() ? document()->url() |
| 298 : KURL(KURL(), targetOrigin->toString()); | 305 : KURL(KURL(), targetOrigin->toString()); |
| 299 if (frame()->securityContext()->isSandboxed(SandboxOrigin) || | 306 if (frame()->securityContext()->isSandboxed(SandboxOrigin) || |
| 300 callingWindow->document()->isSandboxed(SandboxOrigin)) { | 307 callingWindow->document()->isSandboxed(SandboxOrigin)) { |
| 301 message = "Blocked a frame at \"" + | 308 message = "Blocked a frame at \"" + |
| 302 SecurityOrigin::create(activeURL)->toString() + | 309 SecurityOrigin::create(activeURL)->toString() + |
| 303 "\" from accessing a frame at \"" + | 310 "\" from accessing a frame at \"" + |
| 304 SecurityOrigin::create(targetURL)->toString() + "\". "; | 311 SecurityOrigin::create(targetURL)->toString() + "\". "; |
| 305 if (frame()->securityContext()->isSandboxed(SandboxOrigin) && | 312 if (frame()->securityContext()->isSandboxed(SandboxOrigin) && |
| 306 callingWindow->document()->isSandboxed(SandboxOrigin)) | 313 callingWindow->document()->isSandboxed(SandboxOrigin)) |
| 307 return "Sandbox access violation: " + message + | 314 return "Sandbox access violation: " + message + |
| 308 " Both frames are sandboxed and lack the \"allow-same-origin\" " | 315 " Both frames are sandboxed and lack the \"allow-same-origin\" " |
| 309 "flag."; | 316 "flag."; |
| 310 if (frame()->securityContext()->isSandboxed(SandboxOrigin)) | 317 if (frame()->securityContext()->isSandboxed(SandboxOrigin)) |
| 311 return "Sandbox access violation: " + message + | 318 return "Sandbox access violation: " + message + |
| 312 " The frame being accessed is sandboxed and lacks the " | 319 " The frame being accessed is sandboxed and lacks the " |
| 313 "\"allow-same-origin\" flag."; | 320 "\"allow-same-origin\" flag."; |
| 314 return "Sandbox access violation: " + message + | 321 return "Sandbox access violation: " + message + |
| 315 " The frame requesting access is sandboxed and lacks the " | 322 " The frame requesting access is sandboxed and lacks the " |
| 316 "\"allow-same-origin\" flag."; | 323 "\"allow-same-origin\" flag."; |
| 317 } | 324 } |
| 318 | 325 |
| 319 // Protocol errors: Use the URL's protocol rather than the origin's protocol s
o that we get a useful message for non-heirarchal URLs like 'data:'. | 326 // Protocol errors: Use the URL's protocol rather than the origin's protocol |
| 327 // so that we get a useful message for non-heirarchal URLs like 'data:'. |
| 320 if (targetOrigin->protocol() != activeOrigin->protocol()) | 328 if (targetOrigin->protocol() != activeOrigin->protocol()) |
| 321 return message + " The frame requesting access has a protocol of \"" + | 329 return message + " The frame requesting access has a protocol of \"" + |
| 322 activeURL.protocol() + | 330 activeURL.protocol() + |
| 323 "\", the frame being accessed has a protocol of \"" + | 331 "\", the frame being accessed has a protocol of \"" + |
| 324 targetURL.protocol() + "\". Protocols must match.\n"; | 332 targetURL.protocol() + "\". Protocols must match.\n"; |
| 325 | 333 |
| 326 // 'document.domain' errors. | 334 // 'document.domain' errors. |
| 327 if (targetOrigin->domainWasSetInDOM() && activeOrigin->domainWasSetInDOM()) | 335 if (targetOrigin->domainWasSetInDOM() && activeOrigin->domainWasSetInDOM()) |
| 328 return message + | 336 return message + |
| 329 "The frame requesting access set \"document.domain\" to \"" + | 337 "The frame requesting access set \"document.domain\" to \"" + |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 423 | 431 |
| 424 page->focusController().focusDocumentView(frame(), true /* notifyEmbedder */); | 432 page->focusController().focusDocumentView(frame(), true /* notifyEmbedder */); |
| 425 } | 433 } |
| 426 | 434 |
| 427 DEFINE_TRACE(DOMWindow) { | 435 DEFINE_TRACE(DOMWindow) { |
| 428 visitor->trace(m_location); | 436 visitor->trace(m_location); |
| 429 EventTargetWithInlineData::trace(visitor); | 437 EventTargetWithInlineData::trace(visitor); |
| 430 } | 438 } |
| 431 | 439 |
| 432 } // namespace blink | 440 } // namespace blink |
| OLD | NEW |