Who Can Crash the Browser First?!

## Metadata
- Author: [[YouTube]]
- Full Title: Who Can Crash the Browser First?!
- Category: #articles
- Document Tags: [[h1]] [[research]] [[security]] [[testing]] [[xref]]
- Summary: Who Can Crash the Browser First?!
- URL: https://www.youtube.com/watch?v=apoW1TC_m0w
To the moon. To the moon. Three, two, one, go. All right, we are trying to crash the tab. Uh, the first person to crash the browser. Freeze the tab or make the tab become unresponsive wins. So, the challenge is to crash the tab. Really, the first thing is we need to make it unresponsive. So, I just have this page. It's completely blank. Before I try and crash the tab though, we need to add dark mode. So, I'm going to add some styles so that way I'm not blinded
by it. >> We're going to crash this whole browser. The strategy that I want to have, I want to open a URL. I'm going to open my own site. What are the possible ways that a browser tab could crash? There's things that go wrong at a low level. Um, generally web GPL um or web GPU stuff, but that's very hard to get into. Um, you could cause a memory leak, which would which should detach and you simply just fill up the memory in in the browser. We could try to use like a synchronous API like like local storage and try to fill it up. I'm going to
start by just doing a while loop. I think literally if I just do a while true loop, this is going to cause the page to be unresponsive. So we can see there's like a little spinner there. What we want to see is like this page is not responding. Like I can open the dev tools, but like the elements aren't popping up. It might have some protection against like just an infinite loop. Yeah, it's not exactly crashing yet. So let's just do this. Let's try to make an array where we just fill it with tons and tons of data.
>> Now, let's make a giant JavaScript loop. Let's just have an infinite loop. Okay. And an infinite loop is going to essentially just be a straight up like for loop or you could just say while true window open. Okay, look at these tabs cook. Baby, look at them tabs cook. How many tabs we got? How many tabs we got? When's this browser going to crash? Oh, baby. >> What? At some point, we can't push any more data into the array. Let's try again. The other thing we could do is look at the there's Yeah, there's a task manager for Chrome, and it tells us how
much memory is being used. Yeah. So, this tab is using 2 GB of memory. And so, Chrome has really good sandboxing where like each tab, I'm guessing, probably can't use more than 2 GB of memory. And then it just like stops it from trying to use anymore. >> Let's do a index variable and increase that. We'll set the local storage index crash to test. Oh boy, look. This is this is chugging already. Oh, look at my spinner. My spinner is is already
lagging cuz I'm up to millions and millions of events. Uh it's opening so many different tabs right now. It's starting to slow down. And I know we were talking about just crashing an individual page, but uh this the amount of tabs that I have working right now is on another level. The computer is absolutely starting to slow down. Let's do Btop. Oh, it won't even let me visit my term here. What if we just do something like data fill fill it with
zeros from zero to a really big number like over and over again? I feel like if we simply just run out of memory that might cause it. But this is also very frustrating to iterate on. So while that's working, I'm going to make a huge array const lots of data. Let's make a massive array and fill it. How close are we to crashing, folks? I mean, the
computer activity monitor won't even load. It won't even uh Chrome is currently eating up just a massive amount of energy. It is currently using 138% of my CPU. Really just opening up a billion tabs. Uh ver Chrome Web Helper is now using 4 gigs. We have 100% CPU usage. But it's not saying this page is not responding. This is probably really hard to do in general. Like Chrome does everything it can to prevent stuff like this from happening. That's the goal of
isolating these tabs is just so like every website can't just crash your whole browser. So, that's not doing much. I'm trying to think, is there anything else we could do just to get it to freeze? Like, right now, we're using a ton of memory because they're just filling this array over and over again. Also, a lot of processing. Also, this while true loop is just running forever. Oh my gosh. I I It's already becoming unresponsive. This while loop simply just console logging. Come on. Come on. Crash, brother. We're almost at a million console logged hello worlds.
>> At what point is Chrome going to say mercy here? It is now eating up 174% of my CPU. The amount of tabs it's opening is an absurd degree. I wish I could actually find out how many tabs this is opening up. Let's check out the task manager in Chrome if this will even open. It's like it won't even it won't even like let me select this. I think I'm doing it, folks. Come on. Okay. Well, this is a bit of an issue because it technically hasn't crashed, but I I
can't keep working on it. Come on, baby. 1.2 million. Hasn't updated in a while. >> Oh my god, my computer is struggling. The home of Scott Tinsky is now open more times. The task manager is officially not rendering. Oh, it's hitting YouTube all these times, too, cuz there's an iframe in there. Things are really starting to come to a crawl. What else could we do possibly? Um, is there something like max safe integer? I want to see what is the maximum length
because this basically ends at some point. It's definitely slowing the browser down. Oh, baby. Look at the look at the memory climb. How much memory do I have, though? I have 64 gigs of memory. I think we might be here for a bit. Oh, I opened up a whole bunch of new tabs while I was trying to click on it. But this is this is entirely frozen. Let's see. Okay, we we're at 200% CPU usage now. That's great. The thing is I am using light server so it could have like actually cached could have potentially cached the uh previous
version of this but we definitely want to like load it fresh. Okay. I can't click anything in the tab now. Oh. Oh. Spinning wheel. Spinning wheel. No. Oh, come on baby. Come on baby. I'm going to try to click on a bunch of stuff. Try to stress it out. Where's my activity monitor at? 10 gigs. My computer is cooking. The fans are on. I could put an egg on this thing. Let Let's point this microphone at the fans. Uh, it is 199% of my CPU. Uh, Chrome
rendering now is using 8 gigs of RAM. Wes is waving his arms around like an octopus or something. My video right now is like so laggy on the stream. Luckily, I'm recording locally. Come on, fill this sucker up. I should have had a bunch more stuff running so I don't have so much memory. Oh my god, the tabs are still loading. They're still loading. I cannot do anything here. This is hilarious.
OH, I DID IT. A hard crash. Hard crash. It didn't even freeze or anything. Okay, it looks like it looks like Wes did it. Here we go. Hold on. Can I Is this on my screen right now? Here we go. Google Chrome Canary quit unexpectedly. So, what the move was? I believe I think I was just the console log in a while loop. That was way easier than I thought. I win. I think. Let's see what the guys are at. Uh Wes, my browser is frozen, but it hasn't crashed yet.
>> I was there, brother. And I also have a console log in a while loop, but I've got like three tabs. I can't click anything. Uh the the Chrome task manager says it's at like 200%. Oh, no. I The Chrome Task Manager is even frozen, but the browser hasn't crashed. So >> just wait. What did you console log? >> Initially I created an empty array and was just pushing data into it in a while loop. And then I wanted to see okay well what's the longest length? So the moment I went to log data.length is now it's
crashed >> or like it's it's frozen because it it has to count the items in the array to know the length and oh that's the move. >> And every time it pushes in it tries to log it out. Did you crash the whole browser? >> The whole browser. And I got it pulled up right here. Google Chrome Canary quit unexpectedly. >> What I did is I had an infinite while loop opening a new browser tabs to my website. I'm essentially >> new tabs. >> It's opening new tabs. So it it probably has like 10 billion tabs open right now.
And >> that's a good play. >> That's a good move. >> Oh, I crashed the tab. It says all snap. >> Nice. That that took way too long though. I was sitting here for like 3 4 minutes before it finally was like, "Okay, crash the tab." Yeah, my Chrome is completely unresponsive. It has not crashed yet, though. >> You got to wait. >> Chrome can hardly handle 20 tabs. >> Should we try it again without using a while loop or no loops? >> No loops. >> Yeah. Why the heck not?
>> You You ready, Scott? >> Uh, yes. >> Yeah, I'm I'm ready. I'll figure it out. >> All right, we're doing it again. The rules are no loops. No looping. No for in, for of for each, none of that. My idea here is let's add a div to the page and when that div loads, add another div to the page. Okay, the browser works just fine. It's not it's not loading anything, but we can't use a while loop.
But I think we can potentially try to use recursion and crash it in the same way. Possibly not because at a certain point it's going to run into the length being too long. So, I'm just going to create a function called add item that does the same stuff and then calls itself again. >> I would love to figure out how to create a giant image uh B 64 or some kind of CPU decoding thing. I do know that decoding B 64 can be really intense.
>> This is like a loop, but it's using the call stack because it will call itself and then push the call onto the call stack and then call itself again. We also could run into a Stack Overflow because it would call itself too many times. But let's see. >> Then we'll say element.adde eventlister load console log loaded. What's the event? Maybe we should make it an image. I found a base 64 image generator. This thing is big. And we were talking about loading it with CSS. That would be fun.
So, let me just add a style tag in here. And let's set the background background uh or sorry, let's set the body background image to be a URL and have this be this fake B 64 image that I created. Then we'll simply just rerun the add element. That's kind of slow. What if I add a lot of them at once? Yeah, there's no chance this is ever going to crash the browser. So we get to
a point and then its maximum call stack size exceeded because it can't call itself anymore. So what if we instead of calling it directly, we pushed it into the queue with a set timeout or like set immediate. So we'll do a set timeout of zero with the function itself. So that way it's not in the call stack, but it does keep trying to console log and keep trying to push things in. Maximum call stack. Yeah, there's a browser has protections for that. set time out after
0 milliseconds. Uh, it just puts at the end of the event loop. It's not that's not fast enough. Okay, so new idea. Let's just try and make a whole bunch of elements and add them to the page. Okay, so we have this giant image and this is clearly not sweating the browser at all just yet. But what if I just make this even bigger with a bunch of fake information? um generate an image that is billion pixels by a billion pixels. Am I gonna crash just uh I crash the B 64 image
generator, but I can't crash my own tab. >> I mean, that's pretty good. It's only now by uh pushing it off with set interval. It's only using 2% CPU usage instead of uh 200% CPU usage. So, this is one way to not freeze the browser. Here's the other thing I didn't think about, though. Literally having the dev tools open might actually crash the tab too cuz you can see the dev tools the memory and CPU usage of just the dev tools is actually pretty high. I guess that honestly I think that does count cuz that's what happened before is it
had too many console logs and that's what crashed it. >> Oh, what if we return a span document.body html inside of it and then we'll just say document. Yeah, no we're not using we should just use straight up concatenation here. So document.body.inht inner HTML plus equals. This is not never a good idea. >> I'm curious how we could use recursion without using set interval without having a stack overflow. Like I think we
saw when it got to a size of 800, it would overflow the stack. So we could say something like so log the length and then if data.length length is equal to 400, then do I guess stop calling it and then reset the length and then do a set timeout so it doesn't stack overflow. This is not working as well as I thought. All right, screw this. Let's do console log the elements. See what we're working with here. Oh, it's cuz I didn't call the
freaking function. I'm such an idiot. Holy. just add some crazy high values in CSS like break crash the rendering engine make the site slow down. These are all ridiculous ideas here. What if I said instead of pixels, what if this was rims? Um more relative units there. So still nothing. I guess this is cuz this is the body. What if this was a div? What if we had div here? So the my thought here is initially it's going to be doing it locally like in the call stack, but then when the length reaches
400, it clears the call stack by using a set timeout. So that way it doesn't do a stack overflow. Let's see what this does. Okay, this has much higher CPU usage. So we're getting to like 100% CPU usage and then it's like clearing back out. Um, let's go even more. So if the length is let's say like 850. >> Yeah, this is hardly eating up anything. Just keep adding zeros onto this. What if we did a like a animate and the animate is going to be named rotate
100%. Rotate 360° and then the animation name is going to be rotate. There we go. Okay, we're spinning, brothers. We're spinning. We're spinning. All right, look at this. We're adding. Let's look at our activity monitor here. We're at 7 gigs already, brother. again. Only about 110 CPU, but our Dev Tools memory footprint is 5 gigs. So that's that's a good sign. What if we fire off five of them? Maybe what
we do is we do a we don't clear the array, but we use a set timeout. So that actually clears the call stack, but we keep increasing the size of the array. So we'll say like if the length is divisible by 850, then clear the call stack. >> Let's see this baby rotate. Hell yeah. What if we made the animation time even faster? It doesn't like that. The browser clearly doesn't like that. It says, "No, thank you. I don't like that." But it we're not any closer to
crashing. What if we had billion copies of this div? It maybe the uh rotation I need the I need the rotation to draw to draw. It's not animating anymore. I don't know if it's because I crushed something in here that would cause this to not animate. Like what if we just said 1 second rotate 1 second. There we go. Okay, we have one of these. It's rotating 1 second. We have a ton of these. What if now we add an animation delay to the odd numbers of these?
>> Okay, my fans are spinning up and we can't see the dev tools anymore. This is good. We're at 200% CPU usage. Okay, this was the play. So now it's not running into a stack overflow because every time we get like up to 850 uh function calls, it then clears that stack by setting an interval and then it can recall it again. So yeah, our memory usage is increasing. Our CPU is at 200%.
Now we just wait. I think this is a very similar scenario to what we had last time. Let's just add let's make a function called add listeners where we grab all elements and we add an event listener to each one. >> No loop >> and then when that is done we will just call add listeners. All right let's make these things even faster. Now we now have about 200 divs 150 divs all rotating fractions of a second delayed
by a certain amount of time. They are giant base 64 images. They're absolutely freaking out. They are pissed off. >> You know what? What happens if I open up several of these tabs? Scott was doing that. Is that spiking? We're at 9.8 gigs here. Oh, baby. To the moon. To the moon. Starting to lag. We still got 10 gigs of Oh my gosh. The video with these guys is like two frames a second right now. We're up to 2
and 12 gigs and the CPU has died down a bit. Chrome is t Chrome has taken over, but we're almost to 6 gigs of memory used. Um, that's that's an accomplishment. 7 gigs, but we're still only at 100% CPU usage. These extra tabs are doing nothing. Oh no. Oh, page unresponsive, but my Riverside just disconnected.
Wes's camera just cut off. So, >> uh, Wes has now left the chat. I do have kind of a neat kind of cool thing going on over here. What if we zoom in on that? Let's just keep like, what if the What if we also did a zoom? Oh, yeah. Look at this rave we got going on over here. Honestly, this is pretty crazy. >> Yeah. My my play here is just overload it with memory and make it work a lot. So, yeah, we're at 200% CPU usage. Before we had we were using like 8 gigs
of memory. Um, but it still hasn't crashed. It's so funny to me that this isn't crashing the browser like the other one was. And I guess it's kind of because we're every now and then we're offloading the task to the the background by using a set timeout. So, it's just like every 850 function call. Oh, yes. Crashed it. >> I believe that's a win. Okay. I believe I won. But also, our recording, which I'm using a different browser for, just
crashed. >> Oh yeah, look at that browser. Memory footprint riding up here. All right, what if we scaled quite a bit more? Okay, so Oh yeah, now we're just getting colors. It's trying to process this thing. And okay, let's dial back and let's do the translate now by 100 VH each of them. So they're just now going to be like moving like crazy. Boom. Boom. Boom. Boom. This is the world's worst canvas animation. >> Finally. Finally. But it um it just took
that long for it to kick in. It took probably like two, three times as long just to actually crash the tab. But we did it. We crashed it. And Wes still isn't back. Hopefully, we'll see him soon. >> I'm going to I'm going to for There we go. There's my a snap. Result code hung. Okay. I I literally can't even I need to quit Chrome entirely. It feels like I'm like getting to the precipice of crashing the browser, but I cannot seem to crash this bad boy. Okay, let me
share my entire screen so I can show you at least uh the code. >> Oh man, please tell me use B 64. I think I saw that. >> Yeah, used B 64. I did a big B 64 image and then I have a ton of them. Yeah. And then I have a rotate that's happening fractions of a second that's also scaling and translating. It's a rave >> with Yeah, it's a total rave. Without this, it's just looks like this >> forever and ever. I'm actually impressed that it I mean, my CPU is like massively
crunched right now, but I cannot get it to crash. >> Even though you didn't crash it, I I want to say you're the winner of this one because that is such a good way, you know, rather than just using data, you're using straight up like UI B64. Those things always are sluggish when they start to get very big. >> Yeah. Based on personal experience. So for mine, I wanted to do it recursively, but I was running into a stack overflow. So I have same as before with loop, but
instead of in a loop, it's just a recursive function. So every time it calls itself to push into the array and then log the length, but the moment the length hit about 800, it would just say stack overflow >> because it couldn't call itself anymore. So what I did was when it every time it hit about 850, I would then use set timeout which clears the stack, sends it to the background and then keeps calling itself over and over again. So this was
one way to not get the stack overflow but still have it recursively calling itself. Ah, >> and then I just have 10 of those all going at the same time. So just 10 separate functions filling up an array and calling itself and then clearing it from the queue. And this took probably three times as long to crash the browser, but eventually it did. >> That's very impressive. Yeah, >> I started with adding an element and then trying to listen for the I added an image that had a bad source
>> and then I added an event listener that when it errored out it add an element that was way too slow because it like that uses the event loop properly and it just keeps putting things onto the event loop and it goes as fast as it can. So, I scrapped that idea entirely and I just added a million spans where the inside of the span would be the document body inner HTML. Um, and then that didn't do it. It started really slowing it down, but it didn't do it. So, I added a listen to every element on
the page because I think that it added the elements right away, but the renderer was having a trouble rendering 100 elements, but then it it went ahead and started adding the event listeners to a million elements. >> Yeah. >> And oh I used a four each. >> Dang. >> No, that's a big old disqualified Wes cheating again. disqualified myself. I
cheated. >> I'm actually surprised how somewhat easy it was to crash the browser. Like, I thought there were a lot more protections here around all that. >> I had a hard time, honestly. >> Great job, everybody. You all can write some awful code. Let us know down in the comments how you would crash a browser or who how you've accidentally crashed a browser., Who Can Crash the Browser First?!, YouTube, 01kap5f189aa7yf6jhs5qmf181.