OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |