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

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

Issue 2972073002: Mitigate the pushState IPC storm DoS. (Closed)
Patch Set: Simpler data model. Thanks dcheng! 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 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 } 109 }
110 110
111 HistoryScrollRestorationType History::ScrollRestorationInternal() const { 111 HistoryScrollRestorationType History::ScrollRestorationInternal() const {
112 HistoryItem* history_item = 112 HistoryItem* history_item =
113 GetFrame() ? GetFrame()->Loader().GetDocumentLoader()->GetHistoryItem() 113 GetFrame() ? GetFrame()->Loader().GetDocumentLoader()->GetHistoryItem()
114 : nullptr; 114 : nullptr;
115 return history_item ? history_item->ScrollRestorationType() 115 return history_item ? history_item->ScrollRestorationType()
116 : kScrollRestorationAuto; 116 : kScrollRestorationAuto;
117 } 117 }
118 118
119 // TODO(crbug.com/394296): This is not the long-term fix to IPC flooding that we
120 // need. However, it does somewhat mitigate the immediate concern of |pushState|
121 // and |replaceState| DoS (assuming the renderer has not been compromised).
122 bool History::IsFloodingState(const String& hostname) const {
Łukasz Anforowicz 2017/07/07 21:05:17 |hostname| parameter is unused now and can be remo
palmer 2017/07/07 21:38:17 Done.
123 const int kStateUpdateLimit = 50;
124
125 if (state_flood_guard.count > kStateUpdateLimit) {
126 constexpr auto kStateUpdateLimitResetInterval = TimeDelta::FromSeconds(10);
dcheng 2017/07/07 21:04:09 Nit: static
palmer 2017/07/07 21:38:17 Done.
127 const auto now = TimeTicks::Now();
128 if (now - state_flood_guard.last_updated > kStateUpdateLimitResetInterval) {
129 state_flood_guard.count = 0;
130 state_flood_guard.last_updated = now;
dcheng 2017/07/07 21:04:09 Do we want to allow in this case, since > 10 secon
Łukasz Anforowicz 2017/07/07 21:05:17 TL;DR: Do you need a |return false| statement abov
palmer 2017/07/07 21:38:17 Yep, done.
131 }
132 return true;
133 }
134
135 state_flood_guard.count++;
136 return false;
137 }
138
119 bool History::stateChanged() const { 139 bool History::stateChanged() const {
120 return last_state_object_requested_ != StateInternal(); 140 return last_state_object_requested_ != StateInternal();
121 } 141 }
122 142
123 bool History::IsSameAsCurrentState(SerializedScriptValue* state) const { 143 bool History::IsSameAsCurrentState(SerializedScriptValue* state) const {
124 return state == StateInternal(); 144 return state == StateInternal();
125 } 145 }
126 146
127 void History::back(ScriptState* script_state) { 147 void History::back(ScriptState* script_state) {
128 go(script_state, -1); 148 go(script_state, -1);
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
209 void History::StateObjectAdded(PassRefPtr<SerializedScriptValue> data, 229 void History::StateObjectAdded(PassRefPtr<SerializedScriptValue> data,
210 const String& /* title */, 230 const String& /* title */,
211 const String& url_string, 231 const String& url_string,
212 HistoryScrollRestorationType restoration_type, 232 HistoryScrollRestorationType restoration_type,
213 FrameLoadType type, 233 FrameLoadType type,
214 ExceptionState& exception_state) { 234 ExceptionState& exception_state) {
215 if (!GetFrame() || !GetFrame()->GetPage() || 235 if (!GetFrame() || !GetFrame()->GetPage() ||
216 !GetFrame()->Loader().GetDocumentLoader()) 236 !GetFrame()->Loader().GetDocumentLoader())
217 return; 237 return;
218 238
239 if (IsFloodingState(GetFrame()->GetDocument()->GetSecurityOrigin()->Host())) {
240 return;
241 }
242
219 KURL full_url = UrlForState(url_string); 243 KURL full_url = UrlForState(url_string);
220 if (!CanChangeToUrl(full_url, GetFrame()->GetDocument()->GetSecurityOrigin(), 244 if (!CanChangeToUrl(full_url, GetFrame()->GetDocument()->GetSecurityOrigin(),
221 GetFrame()->GetDocument()->Url())) { 245 GetFrame()->GetDocument()->Url())) {
222 // We can safely expose the URL to JavaScript, as a) no redirection takes 246 // 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 247 // place: JavaScript already had this URL, b) JavaScript can only access a
224 // same-origin History object. 248 // same-origin History object.
225 exception_state.ThrowSecurityError( 249 exception_state.ThrowSecurityError(
226 "A history state object with URL '" + full_url.ElidedString() + 250 "A history state object with URL '" + full_url.ElidedString() +
227 "' cannot be created in a document with origin '" + 251 "' cannot be created in a document with origin '" +
228 GetFrame()->GetDocument()->GetSecurityOrigin()->ToString() + 252 GetFrame()->GetDocument()->GetSecurityOrigin()->ToString() +
229 "' and URL '" + GetFrame()->GetDocument()->Url().ElidedString() + "'."); 253 "' and URL '" + GetFrame()->GetDocument()->Url().ElidedString() + "'.");
230 return; 254 return;
231 } 255 }
232 256
233 GetFrame()->Loader().UpdateForSameDocumentNavigation( 257 GetFrame()->Loader().UpdateForSameDocumentNavigation(
234 full_url, kSameDocumentNavigationHistoryApi, std::move(data), 258 full_url, kSameDocumentNavigationHistoryApi, std::move(data),
235 restoration_type, type, GetFrame()->GetDocument()); 259 restoration_type, type, GetFrame()->GetDocument());
236 } 260 }
237 261
238 } // namespace blink 262 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698