Chromium Code Reviews| 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 "config.h" | 5 #include "config.h" |
| 6 #include "core/frame/DOMWindow.h" | 6 #include "core/frame/DOMWindow.h" |
| 7 | 7 |
| 8 #include "bindings/core/v8/ScriptCallStackFactory.h" | 8 #include "bindings/core/v8/ScriptCallStackFactory.h" |
| 9 #include "core/dom/Document.h" | 9 #include "core/dom/Document.h" |
| 10 #include "core/dom/ExceptionCode.h" | 10 #include "core/dom/ExceptionCode.h" |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 91 | 91 |
| 92 Frame* child = frame()->tree().scopedChild(index); | 92 Frame* child = frame()->tree().scopedChild(index); |
| 93 return child ? child->domWindow() : nullptr; | 93 return child ? child->domWindow() : nullptr; |
| 94 } | 94 } |
| 95 | 95 |
| 96 bool DOMWindow::isCurrentlyDisplayedInFrame() const | 96 bool DOMWindow::isCurrentlyDisplayedInFrame() const |
| 97 { | 97 { |
| 98 return frame() && frame()->domWindow() == this && frame()->host(); | 98 return frame() && frame()->domWindow() == this && frame()->host(); |
| 99 } | 99 } |
| 100 | 100 |
| 101 bool DOMWindow::isInsecureScriptAccess(DOMWindow& callingWindow, const String& u rlString) | 101 bool DOMWindow::isInsecureScriptAccess(LocalDOMWindow& callingWindow, const Stri ng& urlString) |
| 102 { | 102 { |
| 103 if (!protocolIsJavaScript(urlString)) | 103 if (!protocolIsJavaScript(urlString)) |
| 104 return false; | 104 return false; |
| 105 | 105 |
| 106 // If this DOMWindow isn't currently active in the Frame, then there's no | 106 // If this DOMWindow isn't currently active in the Frame, then there's no |
| 107 // way we should allow the access. | 107 // way we should allow the access. |
| 108 if (isCurrentlyDisplayedInFrame()) { | 108 if (isCurrentlyDisplayedInFrame()) { |
| 109 // FIXME: Is there some way to eliminate the need for a separate "callin gWindow == this" check? | 109 // FIXME: Is there some way to eliminate the need for a separate "callin gWindow == this" check? |
| 110 if (&callingWindow == this) | 110 if (&callingWindow == this) |
| 111 return false; | 111 return false; |
| 112 | 112 |
| 113 // FIXME: The name canAccess seems to be a roundabout way to ask "can ex ecute script". | 113 // FIXME: The name canAccess seems to be a roundabout way to ask "can ex ecute script". |
| 114 // Can we name the SecurityOrigin function better to make this more clea r? | 114 // Can we name the SecurityOrigin function better to make this more clea r? |
| 115 if (callingWindow.frame()->securityContext()->securityOrigin()->canAcces s(frame()->securityContext()->securityOrigin())) | 115 if (callingWindow.frame()->securityContext()->securityOrigin()->canAcces s(frame()->securityContext()->securityOrigin())) |
| 116 return false; | 116 return false; |
| 117 } | 117 } |
| 118 | |
| 119 callingWindow.printErrorMessage(crossDomainAccessErrorMessage(&callingWindow )); | |
|
alexmos
2015/04/15 17:15:17
See my earlier question about printErrorMessage.
| |
| 118 return true; | 120 return true; |
| 119 } | 121 } |
| 120 | 122 |
| 121 void DOMWindow::resetLocation() | 123 void DOMWindow::resetLocation() |
| 122 { | 124 { |
| 123 // Location needs to be reset manually because it doesn't inherit from DOMWi ndowProperty. | 125 // Location needs to be reset manually because it doesn't inherit from DOMWi ndowProperty. |
| 124 // DOMWindowProperty is local-only, and Location needs to support remote win dows, too. | 126 // DOMWindowProperty is local-only, and Location needs to support remote win dows, too. |
| 125 if (m_location) { | 127 if (m_location) { |
| 126 m_location->reset(); | 128 m_location->reset(); |
| 127 m_location = nullptr; | 129 m_location = nullptr; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 178 if (!didHandleMessageEvent) { | 180 if (!didHandleMessageEvent) { |
| 179 // Capture stack trace only when inspector front-end is loaded as it may be time consuming. | 181 // Capture stack trace only when inspector front-end is loaded as it may be time consuming. |
| 180 RefPtrWillBeRawPtr<ScriptCallStack> stackTrace = nullptr; | 182 RefPtrWillBeRawPtr<ScriptCallStack> stackTrace = nullptr; |
| 181 if (InspectorInstrumentation::consoleAgentEnabled(sourceDocument)) | 183 if (InspectorInstrumentation::consoleAgentEnabled(sourceDocument)) |
| 182 stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSize ToCapture, true); | 184 stackTrace = createScriptCallStack(ScriptCallStack::maxCallStackSize ToCapture, true); |
| 183 | 185 |
| 184 toLocalDOMWindow(this)->schedulePostMessage(event, source, target.get(), stackTrace.release()); | 186 toLocalDOMWindow(this)->schedulePostMessage(event, source, target.get(), stackTrace.release()); |
| 185 } | 187 } |
| 186 } | 188 } |
| 187 | 189 |
| 190 // FIXME: Once we're throwing exceptions for cross-origin access violations, we will always sanitize the target | |
| 191 // frame details, so we can safely combine 'crossDomainAccessErrorMessage' with this method after considering | |
| 192 // exactly which details may be exposed to JavaScript. | |
| 193 // | |
| 194 // http://crbug.com/17325 | |
| 195 String DOMWindow::sanitizedCrossDomainAccessErrorMessage(LocalDOMWindow* calling Window) | |
| 196 { | |
| 197 if (!callingWindow || !callingWindow->document()) | |
| 198 return String(); | |
| 199 | |
| 200 const KURL& callingWindowURL = callingWindow->document()->url(); | |
| 201 if (callingWindowURL.isNull()) | |
| 202 return String(); | |
| 203 | |
| 204 ASSERT(!callingWindow->document()->securityOrigin()->canAccess(frame()->secu rityContext()->securityOrigin())); | |
| 205 | |
| 206 SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin(); | |
| 207 String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a cross-origin frame."; | |
| 208 | |
| 209 // FIXME: Evaluate which details from 'crossDomainAccessErrorMessage' may sa fely be reported to JavaScript. | |
| 210 | |
| 211 return message; | |
| 212 } | |
| 213 | |
| 214 String DOMWindow::crossDomainAccessErrorMessage(LocalDOMWindow* callingWindow) | |
| 215 { | |
| 216 if (!callingWindow || !callingWindow->document()) | |
| 217 return String(); | |
| 218 | |
| 219 const KURL& callingWindowURL = callingWindow->document()->url(); | |
| 220 if (callingWindowURL.isNull()) | |
| 221 return String(); | |
| 222 | |
| 223 // FIXME: This message, and other console messages, have extra newlines. Sho uld remove them. | |
| 224 SecurityOrigin* activeOrigin = callingWindow->document()->securityOrigin(); | |
| 225 SecurityOrigin* targetOrigin = frame()->securityContext()->securityOrigin(); | |
| 226 ASSERT(!activeOrigin->canAccess(targetOrigin)); | |
| 227 | |
| 228 String message = "Blocked a frame with origin \"" + activeOrigin->toString() + "\" from accessing a frame with origin \"" + targetOrigin->toString() + "\". "; | |
| 229 | |
| 230 // Sandbox errors: Use the origin of the frames' location, rather than their actual origin (since we know that at least one will be "null"). | |
| 231 KURL activeURL = callingWindow->document()->url(); | |
| 232 // RemoteFrames do not have a document, and their URLs aren't replicated. | |
| 233 // Constructing the URL out of replicated origins should suffice for | |
| 234 // printing error messages. | |
| 235 KURL targetURL = isLocalDOMWindow() ? document()->url() : KURL(KURL(), targe tOrigin->toString()); | |
| 236 if (frame()->securityContext()->isSandboxed(SandboxOrigin) || callingWindow- >document()->isSandboxed(SandboxOrigin)) { | |
| 237 message = "Blocked a frame at \"" + SecurityOrigin::create(activeURL)->t oString() + "\" from accessing a frame at \"" + SecurityOrigin::create(targetURL )->toString() + "\". "; | |
| 238 if (frame()->securityContext()->isSandboxed(SandboxOrigin) && callingWin dow->document()->isSandboxed(SandboxOrigin)) | |
| 239 return "Sandbox access violation: " + message + " Both frames are sa ndboxed and lack the \"allow-same-origin\" flag."; | |
| 240 if (frame()->securityContext()->isSandboxed(SandboxOrigin)) | |
| 241 return "Sandbox access violation: " + message + " The frame being ac cessed is sandboxed and lacks the \"allow-same-origin\" flag."; | |
| 242 return "Sandbox access violation: " + message + " The frame requesting a ccess is sandboxed and lacks the \"allow-same-origin\" flag."; | |
| 243 } | |
| 244 | |
| 245 // Protocol errors: Use the URL's protocol rather than the origin's protocol so that we get a useful message for non-heirarchal URLs like 'data:'. | |
| 246 if (targetOrigin->protocol() != activeOrigin->protocol()) | |
| 247 return message + " The frame requesting access has a protocol of \"" + a ctiveURL.protocol() + "\", the frame being accessed has a protocol of \"" + targ etURL.protocol() + "\". Protocols must match.\n"; | |
| 248 | |
| 249 // 'document.domain' errors. | |
| 250 if (targetOrigin->domainWasSetInDOM() && activeOrigin->domainWasSetInDOM()) | |
| 251 return message + "The frame requesting access set \"document.domain\" to \"" + activeOrigin->domain() + "\", the frame being accessed set it to \"" + ta rgetOrigin->domain() + "\". Both must set \"document.domain\" to the same value to allow access."; | |
| 252 if (activeOrigin->domainWasSetInDOM()) | |
| 253 return message + "The frame requesting access set \"document.domain\" to \"" + activeOrigin->domain() + "\", but the frame being accessed did not. Both must set \"document.domain\" to the same value to allow access."; | |
| 254 if (targetOrigin->domainWasSetInDOM()) | |
| 255 return message + "The frame being accessed set \"document.domain\" to \" " + targetOrigin->domain() + "\", but the frame requesting access did not. Both must set \"document.domain\" to the same value to allow access."; | |
| 256 | |
| 257 // Default. | |
| 258 return message + "Protocols, domains, and ports must match."; | |
| 259 } | |
| 260 | |
| 188 DEFINE_TRACE(DOMWindow) | 261 DEFINE_TRACE(DOMWindow) |
| 189 { | 262 { |
| 190 visitor->trace(m_location); | 263 visitor->trace(m_location); |
| 191 EventTargetWithInlineData::trace(visitor); | 264 EventTargetWithInlineData::trace(visitor); |
| 192 } | 265 } |
| 193 | 266 |
| 194 } // namespace blink | 267 } // namespace blink |
| OLD | NEW |