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
)); |
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() || !frame()) |
| 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() || !frame()) |
| 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 // TODO(alexmos): RemoteFrames do not have a document, and their URLs |
| 233 // aren't replicated. For now, construct the URL using the replicated |
| 234 // origin for RemoteFrames. If the target frame is remote and sandboxed, |
| 235 // there isn't anything else to show other than "null" for its origin. |
| 236 KURL targetURL = isLocalDOMWindow() ? document()->url() : KURL(KURL(), targe
tOrigin->toString()); |
| 237 if (frame()->securityContext()->isSandboxed(SandboxOrigin) || callingWindow-
>document()->isSandboxed(SandboxOrigin)) { |
| 238 message = "Blocked a frame at \"" + SecurityOrigin::create(activeURL)->t
oString() + "\" from accessing a frame at \"" + SecurityOrigin::create(targetURL
)->toString() + "\". "; |
| 239 if (frame()->securityContext()->isSandboxed(SandboxOrigin) && callingWin
dow->document()->isSandboxed(SandboxOrigin)) |
| 240 return "Sandbox access violation: " + message + " Both frames are sa
ndboxed and lack the \"allow-same-origin\" flag."; |
| 241 if (frame()->securityContext()->isSandboxed(SandboxOrigin)) |
| 242 return "Sandbox access violation: " + message + " The frame being ac
cessed is sandboxed and lacks the \"allow-same-origin\" flag."; |
| 243 return "Sandbox access violation: " + message + " The frame requesting a
ccess is sandboxed and lacks the \"allow-same-origin\" flag."; |
| 244 } |
| 245 |
| 246 // 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:'. |
| 247 if (targetOrigin->protocol() != activeOrigin->protocol()) |
| 248 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"; |
| 249 |
| 250 // 'document.domain' errors. |
| 251 if (targetOrigin->domainWasSetInDOM() && activeOrigin->domainWasSetInDOM()) |
| 252 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."; |
| 253 if (activeOrigin->domainWasSetInDOM()) |
| 254 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."; |
| 255 if (targetOrigin->domainWasSetInDOM()) |
| 256 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."; |
| 257 |
| 258 // Default. |
| 259 return message + "Protocols, domains, and ports must match."; |
| 260 } |
| 261 |
188 DEFINE_TRACE(DOMWindow) | 262 DEFINE_TRACE(DOMWindow) |
189 { | 263 { |
190 visitor->trace(m_location); | 264 visitor->trace(m_location); |
191 EventTargetWithInlineData::trace(visitor); | 265 EventTargetWithInlineData::trace(visitor); |
192 } | 266 } |
193 | 267 |
194 } // namespace blink | 268 } // namespace blink |
OLD | NEW |