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!


In this short challenge, we identify a common XSS bypass, which developers could easily miss.

Description of code

Our code shows a pretty basic menu page of links to multiple options, which also supports a deep-link approach, to provide direct access using a single link into a menu item's page. This functionality is implemented by sending a GET argument (a.k.a. query-string argument). The developer did think about the possibility of XSS and hence replaced all the occurrences of the word `javascript` (case insensitive) from the direct link argument.


What’s wrong with that approach?

A word replace approach is not a good sanitization strategy, it is missing common bypass practices, which attackers love!

What would a successful XSS attack look like in this case?

Attackers will always attempt to bypass the sanitization by using common practices such as escaping special characters, but in this case, the easiest approach is to take advantage of the fact that the "replace" method performs only a single pass over the string, to replace the occurrences of a certain substring. With that in mind, strings such as `javajavascriptscript:[malicious code here]` will result with exactly what the developer was trying to prevent after the replace function is completed, which is `javascript:[malicious code here]`.

So what?

While the code injection required to capture the flag is absolutely harmless, once an XSS attack is possible, by using a phishing strategies or other social engineering techniques, they could cause someone to click the link with the payload and execute an attack to hijack session cookies and/or perform actions on their behalf,. Attackers can make requests authenticated as the user (transfer money in a banking application for example) or send data back to them (make API calls and send all the resulting data back). It could escalate and be immensely harmful as well since once attackers are able to run Javascript within the context of a logged-in user it could serve as an entry point, they can then identify and exploit other vulnerabilities such as broken access control (a.k.a. IDOR), weak encryption / hashing and others to execute wider attacks such as taking over an admin account.

Main Takeaways:

  • Choose a proven sanitization strategy:
    After understanding the needs, Google it and use a proven sanitization strategy, in this case it would have been effective to sanitize the argument, which really shouldn't contain anything but letters and maybe numbers. Any regular expression which is validating the charecters in the argument, would be much prefered compared to a word replace.
  • Deep links should be implemented as allow-lists:
    For a close set of options, the argument shouldn't include anything but those valid options. Avoid planning for future flexibility, keep your code tight and open up options only when you need them.


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


Past Challenges

CTFs For Developers