If you're a returning visitor to our CTF Recaps, feel free to dive straight into the insights! For first-time explorers, let us quickly introduce you to the essence of these recaps. Wizer CTFs were introduced to challenge developers, encouraging them to adopt a hacker's mindset and thereby code more securely. This initiative is a pivotal part of our new security awareness training, specially crafted for development teams - Wizer's Secure Code Training for Developers!

After a challenge retires, our Wizer Wizard and CTO, Itzik Spitzen, crafts takeaways that offer valuable insights into the challenge, focusing on the defensive perspective for your script. Curious to test-drive a CTF before delving into the notes? Visit wizer-ctf.com – it's free, and there's something for all skill levels!

Link to challenge #14


In this challenge, we're identifying a DOM Clobbering XSS Injection vulnerability in the code below. Let's dive into it.

Description of code

The code below showcases a small portion of a certain app which allows users to manage the points they gained in the app. In the particular page showcased, the users get a menu of points related actions they can perform in their account, however, for the purpose of demonstrating the vulnerability, the options themselves aren't implemented.


In looking closely at the code of the menu page itself, we can identify the action portion of a mechanism which allows the transfer of points between accounts. The action is protected by a window variable called `transferBalance`, and only if this variable is set to true, a transfer action can be executed. Note that the page also accepts `yourName` and `yourAvatar` variables which are used to display the user's name and avatar in the page.


What’s wrong with that approach?

The code is exposed to a DOM Clobbering vulnerability since `window` global variables can be substituted with global DOM elements.

What would a successful DOM Clobbering attack look like in this case?

An attacker who identifies the vulnerability, can override the undefined `window.transferBalance` variable by injecting a DOM Element with that name which will be parsed by JavaScript as a valid global window value. In this case, the `yourAvatar` argument which is intended to show the user's Avatar picture, can be used to inject a valid DOM element with the id "transferBalance" i.e. <div id="transferBalance"><div>. As part of the payload, the attacker will then also include the two additional arguments required to complete the job which are the `transferTo` account-id and `pointsToTransfer` value, i.e. `...&transferTo=[acct# to transfer points to]&pointsToTransfer=[# of points to transfer]`.

So what?

DOM Clobbering is a type of code-reuse, HTML-only injection attack, where attackers confuse a web application by injecting HTML elements whose id or name attribute matches the name of security-sensitive variables or browser APIs, such as variables used for fetching remote content (e.g., script src), and overshadow their value. DOM Clobbering opens up a crack for attackers to maliciously change the intended behavior of our code. Such payload could be used as a part of a phishing campaign to make logged on users click the link and maliciously transfer points from their logged on account unknowingly. DOM Clobbering could be a pretty dangerous vulnerability, depending on the type of app. DOM Clobbering often leads to XSS Injection through employing the JavaScript engine's designed behavior maliciously against us.

Main Takeaways (Credit to OWASP10 Cheat Sheet Series):

  • Global and window.VARNAME variables aren't always safe to use:
    Any global variables are more prone to being overwritten by DOM Clobbering. Whenever possible, use local variables and object properties. More specifically it is recommended to avoid using objects like `document` and `window` for storing global variables, because they can be easily manipulated.
  • Do Not Trust Document Built-in APIs Before Validation:
    Document properties, including built-in ones, are always overshadowed by DOM Clobbering, especially uninitialized properties. The global variables search algorithm is performed at runtime, and therefore, the value of a global variable can be changed at any time.
  • Use Explicit Variable Declarations:
    If strict mode ("use strict") isn't already enforced in your app, consider enforcing it, and at least always use a variable declarator like `var`, `let` or `const`, which prevents clobbering of the variable, when initializing variables. Note: Declaring a variable with let does not create a property on `window`, unlike var. Therefore, window.VARNAME can still be clobbered (assuming VARNAME is the name of the variable).


Wanna join us on our next challenge? Sign up for our mailing list at wizer-ctf.com.


Past Challenges

CTFs For Developers