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

Side by Side Diff: third_party/WebKit/Source/core/frame/History.cpp

Issue 2972073002: Mitigate the pushState IPC storm DoS. (Closed)
Patch Set: Move the check to |StateObjectAdded|. Created 3 years, 5 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
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2007 Apple Inc. All rights reserved. 2 * Copyright (C) 2007 Apple Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions 5 * modification, are permitted provided that the following conditions
6 * are met: 6 * are met:
7 * 1. Redistributions of source code must retain the above copyright 7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer. 8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright 9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the 10 * notice, this list of conditions and the following disclaimer in the
(...skipping 20 matching lines...) Expand all
31 #include "core/frame/LocalFrame.h" 31 #include "core/frame/LocalFrame.h"
32 #include "core/frame/LocalFrameClient.h" 32 #include "core/frame/LocalFrameClient.h"
33 #include "core/loader/DocumentLoader.h" 33 #include "core/loader/DocumentLoader.h"
34 #include "core/loader/FrameLoader.h" 34 #include "core/loader/FrameLoader.h"
35 #include "core/loader/HistoryItem.h" 35 #include "core/loader/HistoryItem.h"
36 #include "core/loader/NavigationScheduler.h" 36 #include "core/loader/NavigationScheduler.h"
37 #include "core/page/Page.h" 37 #include "core/page/Page.h"
38 #include "platform/bindings/ScriptState.h" 38 #include "platform/bindings/ScriptState.h"
39 #include "platform/weborigin/KURL.h" 39 #include "platform/weborigin/KURL.h"
40 #include "platform/weborigin/SecurityOrigin.h" 40 #include "platform/weborigin/SecurityOrigin.h"
41 #include "platform/wtf/CurrentTime.h"
42 #include "platform/wtf/HashMap.h"
41 #include "platform/wtf/text/StringView.h" 43 #include "platform/wtf/text/StringView.h"
42 44
43 namespace blink { 45 namespace blink {
44 46
45 namespace { 47 namespace {
46 48
47 bool EqualIgnoringPathQueryAndFragment(const KURL& a, const KURL& b) { 49 bool EqualIgnoringPathQueryAndFragment(const KURL& a, const KURL& b) {
48 return StringView(a.GetString(), 0, a.PathStart()) == 50 return StringView(a.GetString(), 0, a.PathStart()) ==
49 StringView(b.GetString(), 0, b.PathStart()); 51 StringView(b.GetString(), 0, b.PathStart());
50 } 52 }
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 111 }
110 112
111 HistoryScrollRestorationType History::ScrollRestorationInternal() const { 113 HistoryScrollRestorationType History::ScrollRestorationInternal() const {
112 HistoryItem* history_item = 114 HistoryItem* history_item =
113 GetFrame() ? GetFrame()->Loader().GetDocumentLoader()->GetHistoryItem() 115 GetFrame() ? GetFrame()->Loader().GetDocumentLoader()->GetHistoryItem()
114 : nullptr; 116 : nullptr;
115 return history_item ? history_item->ScrollRestorationType() 117 return history_item ? history_item->ScrollRestorationType()
116 : kScrollRestorationAuto; 118 : kScrollRestorationAuto;
117 } 119 }
118 120
121 // TODO(crbug.com/394296): This is not the long-term fix to IPC flooding that we
122 // need. However, it does mitigate the immediate concern of |pushState| DoS
123 // (assuming the renderer has not been compromised).
124 bool History::IsHostFloodingPushState(const String& hostname) const {
125 const int kHostPushStateLimit = 50;
126 const HostLimit& current = host_limits.at(hostname);
127
128 if (current.first > kHostPushStateLimit) {
129 const double kHostPushStateLimitResetSeconds = 10.0;
130 double now = MonotonicallyIncreasingTime();
131 if (now - current.second > kHostPushStateLimitResetSeconds) {
132 host_limits.Set(hostname, HostLimit{0, now});
133 }
134 return true;
135 }
136
137 host_limits.Set(hostname, HostLimit{current.first + 1, current.second});
138 return false;
139 }
140
119 bool History::stateChanged() const { 141 bool History::stateChanged() const {
120 return last_state_object_requested_ != StateInternal(); 142 return last_state_object_requested_ != StateInternal();
121 } 143 }
122 144
123 bool History::IsSameAsCurrentState(SerializedScriptValue* state) const { 145 bool History::IsSameAsCurrentState(SerializedScriptValue* state) const {
124 return state == StateInternal(); 146 return state == StateInternal();
125 } 147 }
126 148
127 void History::back(ScriptState* script_state) { 149 void History::back(ScriptState* script_state) {
128 go(script_state, -1); 150 go(script_state, -1);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 void History::StateObjectAdded(PassRefPtr<SerializedScriptValue> data, 231 void History::StateObjectAdded(PassRefPtr<SerializedScriptValue> data,
210 const String& /* title */, 232 const String& /* title */,
211 const String& url_string, 233 const String& url_string,
212 HistoryScrollRestorationType restoration_type, 234 HistoryScrollRestorationType restoration_type,
213 FrameLoadType type, 235 FrameLoadType type,
214 ExceptionState& exception_state) { 236 ExceptionState& exception_state) {
215 if (!GetFrame() || !GetFrame()->GetPage() || 237 if (!GetFrame() || !GetFrame()->GetPage() ||
216 !GetFrame()->Loader().GetDocumentLoader()) 238 !GetFrame()->Loader().GetDocumentLoader())
217 return; 239 return;
218 240
241 if (IsHostFloodingPushState(
242 GetFrame()->GetDocument()->GetSecurityOrigin()->Host())) {
243 return;
244 }
245
219 KURL full_url = UrlForState(url_string); 246 KURL full_url = UrlForState(url_string);
220 if (!CanChangeToUrl(full_url, GetFrame()->GetDocument()->GetSecurityOrigin(), 247 if (!CanChangeToUrl(full_url, GetFrame()->GetDocument()->GetSecurityOrigin(),
221 GetFrame()->GetDocument()->Url())) { 248 GetFrame()->GetDocument()->Url())) {
222 // We can safely expose the URL to JavaScript, as a) no redirection takes 249 // We can safely expose the URL to JavaScript, as a) no redirection takes
223 // place: JavaScript already had this URL, b) JavaScript can only access a 250 // place: JavaScript already had this URL, b) JavaScript can only access a
224 // same-origin History object. 251 // same-origin History object.
225 exception_state.ThrowSecurityError( 252 exception_state.ThrowSecurityError(
226 "A history state object with URL '" + full_url.ElidedString() + 253 "A history state object with URL '" + full_url.ElidedString() +
227 "' cannot be created in a document with origin '" + 254 "' cannot be created in a document with origin '" +
228 GetFrame()->GetDocument()->GetSecurityOrigin()->ToString() + 255 GetFrame()->GetDocument()->GetSecurityOrigin()->ToString() +
229 "' and URL '" + GetFrame()->GetDocument()->Url().ElidedString() + "'."); 256 "' and URL '" + GetFrame()->GetDocument()->Url().ElidedString() + "'.");
230 return; 257 return;
231 } 258 }
232 259
233 GetFrame()->Loader().UpdateForSameDocumentNavigation( 260 GetFrame()->Loader().UpdateForSameDocumentNavigation(
234 full_url, kSameDocumentNavigationHistoryApi, std::move(data), 261 full_url, kSameDocumentNavigationHistoryApi, std::move(data),
235 restoration_type, type, GetFrame()->GetDocument()); 262 restoration_type, type, GetFrame()->GetDocument());
236 } 263 }
237 264
238 } // namespace blink 265 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698