Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 /* | 1 /* |
| 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> | 2 * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org> |
| 3 * 1999 Lars Knoll <knoll@kde.org> | 3 * 1999 Lars Knoll <knoll@kde.org> |
| 4 * 1999 Antti Koivisto <koivisto@kde.org> | 4 * 1999 Antti Koivisto <koivisto@kde.org> |
| 5 * 2000 Simon Hausmann <hausmann@kde.org> | 5 * 2000 Simon Hausmann <hausmann@kde.org> |
| 6 * 2000 Stefan Schimanski <1Stein@gmx.de> | 6 * 2000 Stefan Schimanski <1Stein@gmx.de> |
| 7 * 2001 George Staikos <staikos@kde.org> | 7 * 2001 George Staikos <staikos@kde.org> |
| 8 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. | 8 * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All r ights reserved. |
| 9 * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com> | 9 * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com> |
| 10 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) | 10 * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies) |
| (...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 143 return client; | 143 return client; |
| 144 } | 144 } |
| 145 | 145 |
| 146 ChromeClient& Frame::chromeClient() const | 146 ChromeClient& Frame::chromeClient() const |
| 147 { | 147 { |
| 148 if (Page* page = this->page()) | 148 if (Page* page = this->page()) |
| 149 return page->chrome().client(); | 149 return page->chrome().client(); |
| 150 return emptyChromeClient(); | 150 return emptyChromeClient(); |
| 151 } | 151 } |
| 152 | 152 |
| 153 Frame* Frame::findFrameForNavigation(const AtomicString& name, Frame* activeFram e) | |
| 154 { | |
| 155 ASSERT(activeFrame); | |
| 156 Frame* frame = tree().find(name); | |
|
dcheng
2014/12/13 01:55:48
Not really related to this patch, but I wonder if
Nate Chapin
2014/12/20 00:09:14
That's an interesting question for the future.
| |
| 157 if (!frame || !activeFrame->canNavigate(*frame)) | |
| 158 return 0; | |
|
dcheng
2014/12/13 01:55:48
nullptr
Nate Chapin
2014/12/20 00:09:14
Done.
| |
| 159 return frame; | |
| 160 } | |
| 161 | |
| 162 static bool canAccessAncestor(const SecurityOrigin& activeSecurityOrigin, const Frame* targetFrame) | |
| 163 { | |
| 164 // targetFrame can be 0 when we're trying to navigate a top-level frame | |
| 165 // that has a 0 opener. | |
| 166 if (!targetFrame) | |
| 167 return false; | |
| 168 | |
| 169 const bool isLocalActiveOrigin = activeSecurityOrigin.isLocal(); | |
| 170 for (const Frame* ancestorFrame = targetFrame; ancestorFrame; ancestorFrame = ancestorFrame->tree().parent()) { | |
| 171 const SecurityOrigin* ancestorSecurityOrigin = ancestorFrame->securityCo ntext()->securityOrigin(); | |
| 172 if (activeSecurityOrigin.canAccess(ancestorSecurityOrigin)) | |
| 173 return true; | |
| 174 | |
| 175 // Allow file URL descendant navigation even when allowFileAccessFromFil eURLs is false. | |
| 176 // FIXME: It's a bit strange to special-case local origins here. Should we be doing | |
| 177 // something more general instead? | |
| 178 if (isLocalActiveOrigin && ancestorSecurityOrigin->isLocal()) | |
| 179 return true; | |
| 180 } | |
| 181 | |
| 182 return false; | |
| 183 } | |
| 184 | |
| 185 bool Frame::canNavigate(const Frame& targetFrame) | |
| 186 { | |
| 187 // Frame-busting is generally allowed, but blocked for sandboxed frames lack ing the 'allow-top-navigation' flag. | |
| 188 if (!securityContext()->isSandboxed(SandboxTopNavigation) && targetFrame == tree().top()) | |
| 189 return true; | |
| 190 | |
| 191 if (securityContext()->isSandboxed(SandboxNavigation)) { | |
| 192 if (targetFrame.tree().isDescendantOf(this)) | |
| 193 return true; | |
| 194 | |
| 195 const char* reason = "The frame attempting navigation is sandboxed, and is therefore disallowed from navigating its ancestors."; | |
| 196 if (securityContext()->isSandboxed(SandboxTopNavigation) && targetFrame == tree().top()) | |
| 197 reason = "The frame attempting navigation of the top-level window is sandboxed, but the 'allow-top-navigation' flag is not set."; | |
| 198 | |
| 199 printNavigationErrorMessage(targetFrame, reason); | |
| 200 return false; | |
| 201 } | |
| 202 | |
| 203 ASSERT(securityContext()->securityOrigin()); | |
| 204 SecurityOrigin& origin = *securityContext()->securityOrigin(); | |
| 205 | |
| 206 // This is the normal case. A document can navigate its decendant frames, | |
| 207 // or, more generally, a document can navigate a frame if the document is | |
| 208 // in the same origin as any of that frame's ancestors (in the frame | |
| 209 // hierarchy). | |
| 210 // | |
| 211 // See http://www.adambarth.com/papers/2008/barth-jackson-mitchell.pdf for | |
| 212 // historical information about this security check. | |
| 213 if (canAccessAncestor(origin, &targetFrame)) | |
| 214 return true; | |
| 215 | |
| 216 // Top-level frames are easier to navigate than other frames because they | |
| 217 // display their URLs in the address bar (in most browsers). However, there | |
| 218 // are still some restrictions on navigation to avoid nuisance attacks. | |
| 219 // Specifically, a document can navigate a top-level frame if that frame | |
| 220 // opened the document or if the document is the same-origin with any of | |
| 221 // the top-level frame's opener's ancestors (in the frame hierarchy). | |
| 222 // | |
| 223 // In both of these cases, the document performing the navigation is in | |
| 224 // some way related to the frame being navigate (e.g., by the "opener" | |
| 225 // and/or "parent" relation). Requiring some sort of relation prevents a | |
| 226 // document from navigating arbitrary, unrelated top-level frames. | |
| 227 if (!targetFrame.tree().parent()) { | |
| 228 if (targetFrame == client()->opener()) | |
| 229 return true; | |
| 230 if (canAccessAncestor(origin, targetFrame.client()->opener())) | |
| 231 return true; | |
| 232 } | |
| 233 | |
| 234 printNavigationErrorMessage(targetFrame, "The frame attempting navigation is neither same-origin with the target, nor is it the target's parent or opener.") ; | |
| 235 return false; | |
| 236 } | |
| 237 | |
| 238 LocalFrame* Document::findUnsafeParentScrollPropagationBoundary() | |
| 239 { | |
| 240 LocalFrame* currentFrame = m_frame; | |
| 241 Frame* ancestorFrame = currentFrame->tree().parent(); | |
| 242 | |
| 243 while (ancestorFrame) { | |
| 244 // FIXME: We don't yet have access to a RemoteFrame's security origin. | |
|
dcheng
2014/12/13 01:55:48
Should we fix this while we're here?
Nate Chapin
2014/12/20 00:09:14
Done. Also, moved this function to frame, changed
| |
| 245 if (!ancestorFrame->isLocalFrame()) | |
| 246 return currentFrame; | |
| 247 if (!toLocalFrame(ancestorFrame)->document()->securityOrigin()->canAcces s(securityOrigin())) | |
| 248 return currentFrame; | |
| 249 currentFrame = toLocalFrame(ancestorFrame); | |
| 250 ancestorFrame = ancestorFrame->tree().parent(); | |
| 251 } | |
| 252 return 0; | |
|
dcheng
2014/12/13 01:55:48
nullptr
Nate Chapin
2014/12/20 00:09:14
Done.
| |
| 253 } | |
| 254 | |
| 153 RenderPart* Frame::ownerRenderer() const | 255 RenderPart* Frame::ownerRenderer() const |
| 154 { | 256 { |
| 155 if (!deprecatedLocalOwner()) | 257 if (!deprecatedLocalOwner()) |
| 156 return 0; | 258 return 0; |
| 157 RenderObject* object = deprecatedLocalOwner()->renderer(); | 259 RenderObject* object = deprecatedLocalOwner()->renderer(); |
| 158 if (!object) | 260 if (!object) |
| 159 return 0; | 261 return 0; |
| 160 // FIXME: If <object> is ever fixed to disassociate itself from frames | 262 // FIXME: If <object> is ever fixed to disassociate itself from frames |
| 161 // that it has started but canceled, then this can turn into an ASSERT | 263 // that it has started but canceled, then this can turn into an ASSERT |
| 162 // since ownerElement() would be 0 when the load is canceled. | 264 // since ownerElement() would be 0 when the load is canceled. |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 202 | 304 |
| 203 if (m_owner) { | 305 if (m_owner) { |
| 204 if (m_owner->isLocal()) | 306 if (m_owner->isLocal()) |
| 205 toHTMLFrameOwnerElement(m_owner)->setContentFrame(*this); | 307 toHTMLFrameOwnerElement(m_owner)->setContentFrame(*this); |
| 206 } else { | 308 } else { |
| 207 page()->setMainFrame(this); | 309 page()->setMainFrame(this); |
| 208 } | 310 } |
| 209 } | 311 } |
| 210 | 312 |
| 211 } // namespace blink | 313 } // namespace blink |
| OLD | NEW |