New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.
Starred by 64 users
Status: Fixed
Closed: Nov 30
EstimatedDays: ----
NextAction: ----
OS: Linux , Android , Windows , Chrome , Mac
Pri: 1
Type: Bug

Blocked on:
issue 672370

Sign in to add a comment
Hang bug in history.pushState()
Reported by, Jul 16 2014 Back to list
You can hang the browser immediately. Potential for heap spray, I am not a pro in buffer overflows so I don't know.
TL;DR: Hang browser, 50% cpu, ram filling up 7mb/s.

Chrome Version: 35.0.1916.153 m + stable
Operating System: Windows 8.1

Full attack included, Simplest case:

for(var i = 0; i<1000000; i++){

Type of crash: Browser
Crash State: (Doesn't technically crash, just hang)
Client ID (if relevant): [see statement above]

249 bytes View Download
Project Member Comment 1 by ClusterFuzz, Jul 16 2014
ClusterFuzz is analyzing your testcase. See
Labels: OS-All Pri-2 M-38 Cr-UI-Browser-Navigation Security_Impact-Stable Security_Severity-Low
Status: Available
nasko: Assigning to you as content/browser/frame_host/OWNERS; please re-assign if appropriate.
Comment 3 by, Jul 17 2014
Labels: -Restrict-View-SecurityTeam -Type-Bug-Security -Security_Impact-Stable -Security_Severity-Low Type-Bug
Owner: ----
Summary: Hang bug in history.pushState() (was: Security: Crash/Hang bug in history.pushState())
Removing security bits from the bug. As per, this is not a security bug.

Since this is just a generic DoS in the browser due to huge amount of IPC messages coming in, I'm unassigning myself from it for anyone interested in tackling this problem.
Comment 4 Deleted
Comment 5 by Deleted ...@, Nov 5 2014
I found another case where this occurs:

If you write an endless recursion like following you will get the error 'RangeError: Maximum call stack size exceeded ':

var endless = function() {

But not if you change this recursion to something with history.pushState:

var endless = function() {
	history.pushState(undefined, undefined, window.location.toString().split('#')[0]);
Comment 6 by, Feb 20 2015
 Issue 460291  has been merged into this issue.
Comment 7 by, Feb 23 2015
Nasko: Having 1M history items in a session isn't realistic, would it be possible/reasonable to add a hard limit to the number of history entries?
Comment 8 by, Feb 23 2015
meacer@ - the problem isn't history limit, it doesn't actually go above 50. The underlying issue is that the IPC queue doesn't have a limit, so we have a TON of IPCs queued up because of the pushState call in a loop. It just takes lots of CPU and time to process through the messages.
Comment 9 by, Feb 24 2015
Ah I see, so it's irrelevant of the API accepting/rejecting the input. Good to know, thanks!
Comment 10 by, Nov 18 2015
 Issue 544132  has been merged into this issue.
Comment 11 by, Nov 18 2015
 Issue 544132  was the same thing with a reload instead of pushState.  Agreed that there's not much that can be done without having a rate limiting mechanism for IPC.
 Issue 581237  has been merged into this issue.
Comment 13 by, Jan 27 2016
This bug was turned into a tool for trolls. They post links (, everywhere, from Twitter to Facebook.
Some even clone the JS code and/or obfuscate with URL shortening services.
Comment 14 by, Jan 27 2016
Is it there any form to fix it? I can't use Chrome for more than 45 seconds. I tried erasing my history and that and it isn't possible because Chrome crashes before it erases everything.
Comment 15 by, Jan 27 2016
If Chrome crashes when it restarts, you can delete file "Current Tabs" in your profile folder, or you can disconnect/disable the network.
Just tried it on Windows stable (32-bit)...Looks like it caused an OOM crash in the browser process, after hanging for a bit.
Reported Jul 16, 2014

so google, you had to wait one and a half until this turned into abuse. "Thank you" for not giving a damn about it. now I've lost all my history because of this.
Comment 18 by, Apr 27 2016
is this fixed in Chrome 50?
Comment 19 by, May 17 2016
It's a shame :( Apple fix Safari in iOS 9.3.1 so it doesn't crash anymore.
But Chrome still doesn't fix this issue.
You still risk crashing Chrome anytime you visit a website.
kinuko@, maybe the IPC batching project you are looking into could be extended to enable rate limiting?

How general will the system be?
We're aiming for making it general at least in the loading field, if we're sending too many IPC requests at once that's causing the system frozen I think we could certainly alleviate this issue by batching.
Comment 22 by, May 23 2016
It's great to see some progress in this issue.
I hope that this will landed in Chrome 53.
Project Member Comment 23 by ClusterFuzz, Jun 14 2016
Labels: ClusterFuzz-Verified
Status: Verified
ClusterFuzz testcase is verified as fixed, closing issue.

If this is incorrect, please add ClusterFuzz-Wrong label and re-open the issue.
Labels: -ClusterFuzz-Verified
Status: Assigned
Sorry for the incorrect ClusterFuzz update, please ignore it. Reopening bug.
Comment 25 by, Jun 27 2016
It looks like we have some progress on this nasty issue.
Comment 26 by, Aug 10 2016
 Issue 627688  has been merged into this issue.
Status: Untriaged
Labels: -M-38
 Issue 645706  has been merged into this issue.
Issue 627922 has been merged into this issue.
Components: Internals>Core
kinuko@: Are you still working on the IPC batching project mentioned in comments 20-21?  Can you mark this as blocked on that?

There's not much navigation folks can do about this-- it would work with any flood of IPCs.
Owner: ----
kinuko@ has been exploring batching IPC for loading

Unfortunately I don't think there is any plan for a general system for rate limiting IPC, as of now. Possibly mojo team could help with this with the new system? Moving kinuko to cc.
Labels: -Type-Bug Type-Bug-Security
Changing to bug-security, @sherriff, could you take a look?
Components: Internals>Mojo
Labels: -Pri-2 Security_Impact-Stable Security_Severity-Medium Pri-1
Status: Available
csharrison/creis -- Can you recommend someone from Mojo that might be able to address this?

While it is a DoS, I think it qualifies as a security bug since it completely blocks the users' ability to close a social engineering site, and now it's being actively exploited. It prevents the user from interacting with any security UX.
until we have the IPC throttling, we could just put some rate limiting in place for the pushState API in the renderer, no?
Status: Assigned
I can take a look at this one (or reassign to someone else if there's more appropriate person)
Project Member Comment 39 by, Nov 4 2016
Labels: M-55
#c37, we could, but what is to stop the attackers to move over to replaceState, fragment navigations, localStorage, possibly a handful other ways that I'm missing? We could rely on them giving up since they only know of it by scanning our bug database, but that would be nasty cat/mouse game to be playing.
Excellent, thanks kinuko.

FYI the abuse of this bug is showing up on several security blogs, starting at

nasko -- Agreed, #c37 only fixes the currently-abused method, but it might give us time to be able to address the others.
yeah, I expect that it's going to be easier to backmerge and quicker to implement
Comment 37, 40-42: I do not think we should get into a game of whack-a-mole (by rate limiting pushState), because there are plenty of IPCs the renderer could send to cause DoS in the browser.  Finding some general approach seems required, and Safe Browsing should help block known cases in the meantime.

I agree that we should try to do something about this-- thanks kinuko@ for taking a look!

However, I don't understand why this is rated as a medium severity security bug according to our guidelines.  That's not what our documentation says (because the architecture was never designed to prevent it):
creis--  Re: security-medium, I commented on this in #c35, specifically that this prevents the user from inspecting page-info or interacting with any other security UI. Something like a data:url that's semi-spoofing a legit domain would be impossible to investigate w/o that UI. If the consensus is that that's not sufficient, let's mark it as a regular bug but still push for a merge. I'm fine with that.
Labels: -Type-Bug-Security -Security_Impact-Stable -Security_Severity-Medium Restrict-View-EditIssue Type-Bug
The abuse of this bug for phishing purposes is certainly not a good thing, but the fact that the attack is phishing also clearly underscores that this is not a security vulnerability as defined in our threat model. It's a DoS, and DoS is outside of our threat model because it's unpreventable (particularly this class of DoS), doesn't violate any trust boundaries, and doesn't lead to direct exposure or compromise of user or site data.

I agree that we should try to fix this quickly to prevent further abuse, but we can't ad hoc change our classifications.

I was curious if there are *persistent* effects of a flood of pushState (I agree with comments above that abusing *transient* CPU/memory/IPCs and hanging the browser is not really a security issue).  I found that:

1. There is indeed no limit on the number of history entries that can be created (as long as the URIs of the entries are unique).

2. After creating 50000 history entries (*) and restarting the browser, I didn't observe zny severe impact to the browser performance:

2a. No change to start-up time.
2b. Some slow-down of the omnibox, but nothing severe.
2c. Search and scrolling on chrome://history (the new, material UI) worked fine.

3. I also tried killing the browser process while it was being flooded with pushState calls.  I didn't see any issues (e.g. no corruption of history state) after restarting the browser.

var start = 1;
var count = 1000;
for (i = 0; i < count; i++) {
  var index = start + i;
  history.pushState(index, "test" + index, location.origin + "/" + index);
+gab@ - I wonder if the new, redesigned task scheduler might help prevent one renderer from flooding the message loop and starving other renderers + starving more important browser tasks.  Maybe we could have a TaskTrait that says whether a particular message loop task / callback originated from a renderer (OTOH, I guess that propagating that bit as a callback spawns other callbacks might be challenging).  Is it worth opening a separate bug to track task scheduler considerations around starvation-by-misbehaving-renderer?  FWIW, I've also left a comment/question in
#47 - There're things that can be better throttled / controlled at task level and others that are not (i.e. one single task could screw up things), but yep in general it'd be good to consider how we should handle tasks from misbehaving renderers.
Labels: -M-55 M-57
Sorry for slow updates, I got distracted by other misc stuff / ooo schedule etc.  Now I have a wip patch that does:

* applies basic rate limiting for both traditional and mojo IPC from renderer
* triggers throttling once the renderer starts to send messages more than the given limit for a certain period

This allows the browser and other tabs to continue to just work while loading http://localhost:8000/crash.html or similar other pages.  Current throttling algorithm is not ideal though (naturally), as it's heuristics-based and not getting much signals that might be useful to make better decisions, which could be hopefully done in follow-up changes.  I'll make a short write-up and will start to hear opinion from more people (while the timing may not be quite great as many people will be ooo)

Blockedon: 672370
 Issue 671879  has been merged into this issue.
 Issue 688246  has been merged into this issue.
Issue 648333 has been merged into this issue.
 Issue 412114  has been merged into this issue.
 Issue 702415  has been merged into this issue.
 Issue 710189  has been merged into this issue.
@kinuko, do you have any update on this bug? it would be great to have a plan to attack this as reports keep rolling in about this behavior.
 Issue 716414  has been merged into this issue.
Issue 721477 has been merged into this issue.
 Issue 738470  has been merged into this issue.
Labels: -OS-All -Restrict-View-EditIssue -M-57 allpublic M-61 OS-Android OS-Chrome OS-Fuchsia OS-Linux OS-Mac OS-Windows
I have a mitigation (not solution) CL in progress that will hopefully land in time for M61.

This bug is basically public; opening it up.
We may also want to set a limit on how large the state object can get, and/or find a way to better serialize large objects at the Mojo layer (such as by automatically turning them into shared memory segments when they cross a threshold, or something). The CL as it currently stands helps, but the 'attack' PoC does still make the browser sluggish and a bit unpredictable.
is this about my  issue ??

waiting for your replay as soon as possible .

Thanks in advance .

2017-07-07 23:53 GMT+03:00 pal… via monorail <>:
Project Member Comment 64 by, Jul 11 2017
The following revision refers to this bug:

commit 95558ee76640b366e8b775bd93483b99af379f55
Author: palmer <>
Date: Tue Jul 11 02:33:43 2017

Mitigate the pushState IPC storm DoS.

This is nothing like what the ultimate, true solution should look like. It does
seem to work for the narrow problem of calling history.pushState in a tight
loop, however.

BUG= 394296 

Cr-Commit-Position: refs/heads/master@{#485498}


Issue 651066 has been merged into this issue.
Will this issue started by me and owned by me cause am the first one who reported about it ,So i wish i get a replay for that ,i wanna know what happened to my report ??????


mohacker182:  This doesn't look to have anything to do with any of the bug reports you filed.
no i think it does cause i didn't get any replay about what happened to my report about the vulnerability which is has this Number   Issue 394296 ???
Labels: Restrict-AddIssueComment-EditIssue
That's this issue, and you weren't the reporter of this issue.  Anyhow, not worth wasting developer time figuring out if this was "your" bug or not.
Labels: -Restrict-AddIssueComment-EditIssue
My last post on this bug set the wrong tone - I apologize. I am still having a hard time understanding exactly what you are asking for, and which bug you are referring to. It appears that this bug was reported by someone else, and I don't see any other similar bugs. Please help clear this up.

It looks to me like the only two bugs you filed were  and , neither of which look to me to be related to this issue.
Hi mohacker182@ - I'm a Chrome TPM and help wrangle bugs. If you could mail me a summary of your question to I'll help chase down some answers :-)  Thanks!
Status: Started
This has been set to P1+M61, so this bug needs an active owner.

palmer@: I'm tentatively assigning to you since you landed a CL. Is there more to do? Can you continue to own this bug?
Comment 74 Deleted
There is more to do, but I don't volunteer to do it because I have my own backlog of bugs to handle. :) Sorry. :)

I volunteered to land the quick hack to be friendly, and I think the hack does somewhat mitigate the {push,replace}State problem. For what it's worth.

We know the long-term fix must be in the IPC-receiver-side, and must be generic to all floods (probably including transparently handling huge messages as well as ridiculously frequent messages). (There's been some talk about transparently serializing huge messages as shared memory segments, without making the programmer do it themselves?)

If kinuko doesn't have time to dig into it in the short term, maybe we should raise this issue to the Mojo Gurus?
Comment 76 by, Jul 15 2017
Labels: -OS-Fuchsia
 Issue 757023  has been merged into this issue.
 Issue 759074  has been merged into this issue.
 Issue 759368  has been merged into this issue.
 Issue 761843  has been merged into this issue.
Issue 144450 has been merged into this issue.
 Issue 765379  has been merged into this issue.
Hi all, looks like the changes related to this issue are impacting our test suite as we have a url state management lib with a bunch of fast test cases that use history.replaceState.

So there are two asks:
1. When it fails it would be nice to have feedback given (maybe something logged to the console). Currently, history.replaceState just no-ops without explaining why.
2. Some mechanism to work around this. Maybe a flag that can be used to disable the throttling/limit? We don't expect to ever hit this in production, just in our test cases, so it would be reasonable to run Chromium with a flag.

For reference, original Twitter convo:
Comment 84: That seems like a reasonable proposal.  I've filed issue 769592 to track it.
Status: Fixed
The bug was fixed and pushed out in m61 which went to users in early September, so marking the specific bug about pushstate as fixed.

We can discuss other generic solutions separately.
Sign in to add a comment