Open Bug 1765678 Opened 3 years ago Updated 1 year ago

Crash Browser DoS with pushState()

Categories

(Core :: DOM: Navigation, defect)

Unspecified
Android
defect

Tracking

()

People

(Reporter: ricardo.bughunter, Unassigned)

References

(Blocks 1 open bug, )

Details

(Keywords: csectype-dos, Whiteboard: [reporter-external] [client-bounty-form] [verif?])

Attachments

(1 file)

Attached file crash.html (deleted) —

When a user accesses a malicious link containing this payload, a recursive javascript function is executed, which performs bulk requests causing an overload of memory entries, causing the browser to stop working and totally polluting the browsing history. This script contains a repetition counter generating a recursive redirection counter generating massive buffer overflow entries executed.

Flags: sec-bounty?

Check the status update:

I tested it on Android and iOS apps, both due to the reopening feature of the last accessed tab, the browser will stop working permanently, or until the phone is formatted/application is uninstalled.

The relevant part of the testcase at the Github link:

   var total = "";
   for( var i = 0; i < 100000; i++ ) {
      total = total + i.toString();
      history.pushState(0,0, total );
   }

The string growth is linear-ish rather than exponential (doubling) so I'm guessing this is the pushState IPC traffic jam.

Blocks: eviltraps

The expected behavior is JavaScript must be blocked or sanitized, so as not to cause the browser to crash, even on mobile the application makes it unusable

The default behavior for Firefox for Android should be to revert to the home page after 4 hours, but of course someone with a browser in this state probably won't know/remember that and won't want to wait that long anyway. Worth experimenting to see if a workaround is to kill the stuck browser, then click on a URL or ad in some other app that launches the browser. It might open the new URL without loading the content of the other tabs and then you could close the tab from the tab UI. If that works "Yay" for lazy-loading tabs.

The above comment is not AT ALL saying "it's perfectly fine to crash". I'm just exploring exactly how stuck users might be in that situation. deleting Firefox and reinstalling is not a great solution because people may lose their bookmarks and such if they have not enabled Firefox Sync.

The main problem that depending on android the entire phone dies, especially android 4.0 <

(In reply to Daniel Veditz [:dveditz] from comment #6)

The above comment is not AT ALL saying "it's perfectly fine to crash". I'm just exploring exactly how stuck users might be in that situation. deleting Firefox and reinstalling is not a great solution because people may lose their bookmarks and such if they have not enabled Firefox Sync.

Yes, the problem can be explored in several ways in several scenarios, I believe that the ideal is to sanitize the input to prevent such action, or even block this type of exploitation, as it ends up using the browser service to disable systems, many hospitals in my country uses SAP that uses a technology entirely on top of the browser, if someone runs this script, for example, it would be able to disable a whole series of hospitals, directly affecting reports and prescriptions.
I'm more concerned with providing an extra layer of protection to the firefox browser so that hackers don't use it as an attack vector.

Group: firefox-core-security → dom-core-security
Status: UNCONFIRMED → NEW
Component: Security → DOM: Navigation
Ever confirmed: true
Product: Firefox → Core
Summary: Crash Browser DoS → Crash Browser DoS with pushState()

Hey Paul, in bug 1314912 you added a rate limit for pushState(), but this testcase seems to be doing a similar kind of DoS. Did the limit get lifted? Not set low enough? Is this testcase actually doing something else? I note the reporter is concerned about Android, so it might be a GeckoView/Android Components bottleneck instead, or maybe the Desktop rate-limit needs to be #ifdef ANDROID something lower.

Flags: sec-bounty? → needinfo?(pbz)

Guys got a little confused, I got an email that "sec-bounty canceled" does that mean the topic was closed as not applicable? what does that mean? I'm new to the bugzilla platform, I would like some understanding support...

My concerns are with integrated systems based on GeckoView like the one mentioned above (SAP - Integrated system responsible for a large part of the software in hospitals in Brazil) and users of old androids, without hardware support to be able to self-mitigate this type of exploration.
The main intention is to perform a sanitization in the application in order to protect those people/companies that do not have this technological support to mitigate this type of attack.

Guys got a little confused, I got an email that "sec-bounty canceled" does that mean the topic was closed as not applicable?

Thanks for catching that! I accidentally deleted it when tagging Paul for more information. We're still in an investigation phase.

Flags: sec-bounty?
OS: Unspecified → Android

I can't reproduce this on Desktop Firefox 99.0 (64-bit) on Ubuntu
Can't reproduce on Fenix Nightly 101.0a1 from today either. Tested on a Google Pixel 5.

In both cases the code is aborted with the following rate limiting error:

Too many calls to Location or History APIs within a short timeframe.
Uncaught DOMException: The operation is insecure.
Flags: needinfo?(pbz)

Try accessing this link to see what it returns:
https://output.jsbin.com/najawidedo/1

It's a sandbox I made for testing

Update Notes:

I performed tests in the firefox application on the Oculus Quest 2
App: Firefox Reality
Version: 12.2

Result: The browser crashed the same on old androids, but a little more aggravating because in addition to crashing the oculus, the browser in VR comes as the default setting, restore the last page accessed, unfortunately the Oculus heated up a lot after running this malicious code and I had to format it to factory setting...

(In reply to ricardo.bughunter from comment #14)

Try accessing this link to see what it returns:
https://output.jsbin.com/najawidedo/1

It's a sandbox I made for testing

This appears to be empty, though JSBin also says that the preview time for the anonymous free bin has expired.

Can't you just attach whatever testcase? I assume Paul used the earlier crash.html you attached and couldn't reproduce with that. Firefox Reality is no longer developed by Mozilla (see https://blog.mozilla.org/en/mozilla/news/update-on-firefox-reality/ ). comment #2 suggests you tested on android and iOS - what versions of Fenix (Firefox for Android) and Firefox for iOS did you test with? What devices did you use? And what testcase?

Flags: needinfo?(ricardo.bughunter)

This isn't really anything new, and pushState can break other browsers too
(happens to be particularly easy on some browsers which effectively don't limit the payload size of pushstate at all. In FF the limit is currently 16MB per pushState).

This has been discussed also in HTML spec issues in github, can't just recall now in which one.

Group: dom-core-security
Keywords: csectype-dos
Severity: -- → S3

Do we have any updates on this report?

Flags: needinfo?(ricardo.bughunter)

(In reply to ricardo.bughunter from comment #18)

Do we have any updates on this report?

No. Do you have answers for the questions I asked you in comment 16?

(In reply to :Gijs (he/him) from comment #16)

(In reply to ricardo.bughunter from comment #14)

Try accessing this link to see what it returns:
https://output.jsbin.com/najawidedo/1

It's a sandbox I made for testing

This appears to be empty, though JSBin also says that the preview time for the anonymous free bin has expired.

Can't you just attach whatever testcase? I assume Paul used the earlier crash.html you attached and couldn't reproduce with that. Firefox Reality is no longer developed by Mozilla (see https://blog.mozilla.org/en/mozilla/news/update-on-firefox-reality/ ). comment #2 suggests you tested on android and iOS - what versions of Fenix (Firefox for Android) and Firefox for iOS did you test with? What devices did you use? And what testcase?

Flags: needinfo?(ricardo.bughunter)
Flags: sec-bounty? → sec-bounty-

I've been away for a while, so here we go, do you have any outstanding issues or questions I need to answer?

Flags: needinfo?(ricardo.bughunter)
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: