September 24, 2021

The #13th DOJO CHALLENGE was about to bypassing blacklist and using prototype pollution vulnerability and execute alert(). This DOJO was created by one of our community members. Thanks to him for this great challenge!

💡 You want to create your own DOJO and publish it? Send us a message on Twitter!


We are glad to announce the #13 DOJO Challenge winners list.


  • The best writeups reports were submitted by: Dominikoso, Panya and Yongi

Subscribe to our Twitter or Linkedin feeds to be notified of the upcoming challenges.

Read on to find the best write-up as well as the challenge author’s recommendations.

The challenge

We all know how prototype works, but, is this really a proto here?

See the challenge page >

We asked you to produce a qualified write-up report explaining the logic allowing such exploitation. This write-up serves two purposes:

  • Ensure no copy-paste would occur.
  • Determine the contestant ability to properly describe a vulnerability and its vectors inside a professionally redacted report. This capacity gives us invaluable hints on your own, unique, talent as a bug hunter.


Dominikoso‘sreport was well detailed and really useful to understand the logic of this challenge. All the steps are clearly explained and it’s very useful for everyone to understand how he went about solving this DOJO.

The others reports, notably Panya‘s and Yongi‘s were also very nice, we’re sorry can’t publish them all because that’s where you clearly witness the outstanding creativity of our community.

Thank you all for playing with us!

Pinky‘s Write-Up

————– START OF Dominikoso REPORT ——————


XSS (Cross-Site Scripting) vulnerability occurs when attacker is able to inject his own JavaScript code into webpage source causing it’s execution in victim browser. Commonly XSS may be used to execute actions “as victim”, but combined with other misconfiguration can lead to user’s session takeover.

In DOJO Challenge #13 hunters were given a task to bypassing blacklist and using prototype pollution vulnerability execute alert() on webpage.


Source code of the challenge:

let options = {
  "_allowExecute": false

const config = $config;

function deepCopy(obj1, obj2){
  for (let x in obj2){
    if (typeof obj2[x] === 'object'){
      obj1[x] = deepCopy(obj1[x] || {}, obj2[x]);
       obj1[x] = obj2[x];
  return obj1;

options = deepCopy(options, config);

if (options._allowExecute !== true){
  delete options.code;

if (options.code){
  (new Function(options.code))()

The only parameter controlled by user is $config also there are a blacklist containing two characters: and _. The flow of a task consists of:

  1. Creating new object named options with _allowExecute property set to false
  2. Assigning jsonified user input to config variable
  3. Performing copying of config properties into options object
  4. Checking if options._allowExecute value is strictly in-equal to true. Then if check is passed, script will delete options.code property.
  5. At the end of script if options.code is defined, it’s value is parsed as new Function and then executed.


At first we need to use alternative approach for prototype pollution as we are unable to use __proto__ property due to defined blacklist. But as Object.__proto__ and Object.constructor.prototype can be used interchangeably – which can be checked using simple strict comparison in Web Browser Console:

As prototype pollution vulnerability allows us to change prototype of object, not object on it’s own, setting code property using previously mentioned vulnerability cause that delete will not work for it, as it is not the attribute of options object but it’s prototype.

Now as we now that prototype code property will not be deleted we can proceed to execution of exploit.

Proof of Concept

{ "constructor": { "prototype": {"code":"alert("} } }