Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(874)

Side by Side Diff: content/browser/frame_host/navigation_controller_impl.cc

Issue 317703004: Simplify AreURLsInPageNavigation (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Kill the renderer if it claims a cross-origin in-page navigation Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "content/browser/frame_host/navigation_controller_impl.h" 5 #include "content/browser/frame_host/navigation_controller_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/debug/trace_event.h" 9 #include "base/debug/trace_event.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
97 for (size_t i = 0; i < entries->size(); ++i) { 97 for (size_t i = 0; i < entries->size(); ++i) {
98 // Use a transition type of reload so that we don't incorrectly increase 98 // Use a transition type of reload so that we don't incorrectly increase
99 // the typed count. 99 // the typed count.
100 (*entries)[i]->SetTransitionType(PAGE_TRANSITION_RELOAD); 100 (*entries)[i]->SetTransitionType(PAGE_TRANSITION_RELOAD);
101 (*entries)[i]->set_restore_type(ControllerRestoreTypeToEntryType(type)); 101 (*entries)[i]->set_restore_type(ControllerRestoreTypeToEntryType(type));
102 // NOTE(darin): This code is only needed for backwards compat. 102 // NOTE(darin): This code is only needed for backwards compat.
103 SetPageStateIfEmpty((*entries)[i].get()); 103 SetPageStateIfEmpty((*entries)[i].get());
104 } 104 }
105 } 105 }
106 106
107 // See NavigationController::IsURLInPageNavigation for how this works and why. 107 // There are two general cases where a navigation is in page:
108 // 1. A fragment navigation, in which the url is kept the same except for the
109 // reference fragment.
110 // 2. A history API navigation (pushState and replaceState). This case is
111 // always in-page, but the urls are not guaranteed to match excluding the
112 // fragment. The relevant spec allows pushState/replaceState to any URL on
113 // the same origin.
114 // Howeer, due to reloads, even identical urls are *not* guaranteed to be
nasko 2014/06/06 21:09:45 nit: "However"
115 // in-page navigations, we have to trust the renderer almost entirely.
116 // The one thing we do know that cross-origin navigations will *never* be
nasko 2014/06/06 21:09:45 nit: "is that"
117 // in-page. Therefore, trust the renderer if the URLs are on the same origin,
118 // and assume the renderer is malicious if a cross-origin navigation claims to
119 // be in-page.
108 bool AreURLsInPageNavigation(const GURL& existing_url, 120 bool AreURLsInPageNavigation(const GURL& existing_url,
109 const GURL& new_url, 121 const GURL& new_url,
110 bool renderer_says_in_page, 122 bool renderer_says_in_page,
111 NavigationType navigation_type) { 123 RenderFrameHost* rfh) {
112 if (existing_url.GetOrigin() == new_url.GetOrigin()) 124 bool is_same_origin = existing_url.GetOrigin() == new_url.GetOrigin();
113 return renderer_says_in_page; 125 if (!is_same_origin && renderer_says_in_page)
114 126 rfh->GetProcess()->ReceivedBadMessage();
115 if (!new_url.has_ref()) { 127 return is_same_origin && renderer_says_in_page;
116 // When going back from the ref URL to the non ref one the navigation type
117 // is IN_PAGE.
118 return navigation_type == NAVIGATION_TYPE_IN_PAGE;
119 }
120
121 url::Replacements<char> replacements;
122 replacements.ClearRef();
123 return existing_url.ReplaceComponents(replacements) ==
124 new_url.ReplaceComponents(replacements);
125 } 128 }
126 129
127 // Determines whether or not we should be carrying over a user agent override 130 // Determines whether or not we should be carrying over a user agent override
128 // between two NavigationEntries. 131 // between two NavigationEntries.
129 bool ShouldKeepOverride(const NavigationEntry* last_entry) { 132 bool ShouldKeepOverride(const NavigationEntry* last_entry) {
130 return last_entry && last_entry->GetIsOverridingUserAgent(); 133 return last_entry && last_entry->GetIsOverridingUserAgent();
131 } 134 }
132 135
133 } // namespace 136 } // namespace
134 137
(...skipping 625 matching lines...) Expand 10 before | Expand all | Expand 10 after
760 // Or if we are doing a cross-site redirect navigation, 763 // Or if we are doing a cross-site redirect navigation,
761 // we will do a similar thing. 764 // we will do a similar thing.
762 details->did_replace_entry = 765 details->did_replace_entry =
763 pending_entry_ && pending_entry_->should_replace_entry(); 766 pending_entry_ && pending_entry_->should_replace_entry();
764 767
765 // Do navigation-type specific actions. These will make and commit an entry. 768 // Do navigation-type specific actions. These will make and commit an entry.
766 details->type = ClassifyNavigation(rfh, params); 769 details->type = ClassifyNavigation(rfh, params);
767 770
768 // is_in_page must be computed before the entry gets committed. 771 // is_in_page must be computed before the entry gets committed.
769 details->is_in_page = IsURLInPageNavigation( 772 details->is_in_page = IsURLInPageNavigation(
770 params.url, params.was_within_same_page, details->type); 773 params.url, params.was_within_same_page, rfh);
771 774
772 switch (details->type) { 775 switch (details->type) {
773 case NAVIGATION_TYPE_NEW_PAGE: 776 case NAVIGATION_TYPE_NEW_PAGE:
774 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry); 777 RendererDidNavigateToNewPage(rfh, params, details->did_replace_entry);
775 break; 778 break;
776 case NAVIGATION_TYPE_EXISTING_PAGE: 779 case NAVIGATION_TYPE_EXISTING_PAGE:
777 RendererDidNavigateToExistingPage(rfh, params); 780 RendererDidNavigateToExistingPage(rfh, params);
778 break; 781 break;
779 case NAVIGATION_TYPE_SAME_PAGE: 782 case NAVIGATION_TYPE_SAME_PAGE:
780 RendererDidNavigateToSamePage(rfh, params); 783 RendererDidNavigateToSamePage(rfh, params);
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
979 // the pending entry and go back to where we were (the "existing entry"). 982 // the pending entry and go back to where we were (the "existing entry").
980 return NAVIGATION_TYPE_SAME_PAGE; 983 return NAVIGATION_TYPE_SAME_PAGE;
981 } 984 }
982 985
983 // Any toplevel navigations with the same base (minus the reference fragment) 986 // Any toplevel navigations with the same base (minus the reference fragment)
984 // are in-page navigations. We weeded out subframe navigations above. Most of 987 // are in-page navigations. We weeded out subframe navigations above. Most of
985 // the time this doesn't matter since WebKit doesn't tell us about subframe 988 // the time this doesn't matter since WebKit doesn't tell us about subframe
986 // navigations that don't actually navigate, but it can happen when there is 989 // navigations that don't actually navigate, but it can happen when there is
987 // an encoding override (it always sends a navigation request). 990 // an encoding override (it always sends a navigation request).
988 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url, 991 if (AreURLsInPageNavigation(existing_entry->GetURL(), params.url,
989 params.was_within_same_page, 992 params.was_within_same_page, rfh)) {
990 NAVIGATION_TYPE_UNKNOWN)) {
991 return NAVIGATION_TYPE_IN_PAGE; 993 return NAVIGATION_TYPE_IN_PAGE;
992 } 994 }
993 995
994 // Since we weeded out "new" navigations above, we know this is an existing 996 // Since we weeded out "new" navigations above, we know this is an existing
995 // (back/forward) navigation. 997 // (back/forward) navigation.
996 return NAVIGATION_TYPE_EXISTING_PAGE; 998 return NAVIGATION_TYPE_EXISTING_PAGE;
997 } 999 }
998 1000
999 void NavigationControllerImpl::RendererDidNavigateToNewPage( 1001 void NavigationControllerImpl::RendererDidNavigateToNewPage(
1000 RenderFrameHost* rfh, 1002 RenderFrameHost* rfh,
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1246 const NavigationEntries::const_iterator i(std::find( 1248 const NavigationEntries::const_iterator i(std::find(
1247 entries_.begin(), 1249 entries_.begin(),
1248 entries_.end(), 1250 entries_.end(),
1249 entry)); 1251 entry));
1250 return (i == entries_.end()) ? -1 : static_cast<int>(i - entries_.begin()); 1252 return (i == entries_.end()) ? -1 : static_cast<int>(i - entries_.begin());
1251 } 1253 }
1252 1254
1253 bool NavigationControllerImpl::IsURLInPageNavigation( 1255 bool NavigationControllerImpl::IsURLInPageNavigation(
1254 const GURL& url, 1256 const GURL& url,
1255 bool renderer_says_in_page, 1257 bool renderer_says_in_page,
1256 NavigationType navigation_type) const { 1258 RenderFrameHost* rfh) const {
1257 NavigationEntry* last_committed = GetLastCommittedEntry(); 1259 NavigationEntry* last_committed = GetLastCommittedEntry();
1258 return last_committed && AreURLsInPageNavigation( 1260 return last_committed && AreURLsInPageNavigation(
1259 last_committed->GetURL(), url, renderer_says_in_page, navigation_type); 1261 last_committed->GetURL(), url, renderer_says_in_page, rfh);
1260 } 1262 }
1261 1263
1262 void NavigationControllerImpl::CopyStateFrom( 1264 void NavigationControllerImpl::CopyStateFrom(
1263 const NavigationController& temp) { 1265 const NavigationController& temp) {
1264 const NavigationControllerImpl& source = 1266 const NavigationControllerImpl& source =
1265 static_cast<const NavigationControllerImpl&>(temp); 1267 static_cast<const NavigationControllerImpl&>(temp);
1266 // Verify that we look new. 1268 // Verify that we look new.
1267 DCHECK(GetEntryCount() == 0 && !GetPendingEntry()); 1269 DCHECK(GetEntryCount() == 0 && !GetPendingEntry());
1268 1270
1269 if (source.GetEntryCount() == 0) 1271 if (source.GetEntryCount() == 0)
(...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after
1770 } 1772 }
1771 } 1773 }
1772 } 1774 }
1773 1775
1774 void NavigationControllerImpl::SetGetTimestampCallbackForTest( 1776 void NavigationControllerImpl::SetGetTimestampCallbackForTest(
1775 const base::Callback<base::Time()>& get_timestamp_callback) { 1777 const base::Callback<base::Time()>& get_timestamp_callback) {
1776 get_timestamp_callback_ = get_timestamp_callback; 1778 get_timestamp_callback_ = get_timestamp_callback;
1777 } 1779 }
1778 1780
1779 } // namespace content 1781 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698