Search code examples
javascriptgetter-settergetter

Make js object loop redundant


I'm the tester of a JS api. The user will call our methods directly.

Example:

function funcWeGiveToUser(objFromUsers){
    // here we will loop over user provided object
}

The dev wrote the funcWeGiveToUser in such a way that we're blindly looping over objFromUsers, so I'm trying to prove that by blindly using the object with no validation bad things will happen.

Now I want to see if, by providing an objFromUsers that contains getters, I can somehow break the code (I've already accessed private data through this, yay!).

What I want is to make the object forever changing, so that when our API loops over it, it'll be redundant - but I'm not able to achieve that.

I tried writing such an object:

var objFromUsers = {
    get addNewOne(){
        this.counter = this.counter || 1;
        this["element"+ (this.counter++)] = "some value";
        return 2;
    }
}

But if I loop over it myself, this is the result:

for (el in objFromUsers) console.log(el+": "+objFromUsers[el]);
// addNewOne: 2
console.log(objFromUsers)
// {counter: 2, element1: "some value"}

Looping once more I indeed get the previously added element:

for (el in objFromUsers) console.log(el+": "+objFromUsers[el]);
// addNewOne: 2
// counter: 3
// element1: some value
console.log(objFromUsers)
// {counter: 3, element1: "some value", element2: "some value"}

However, I actually hoped the loop will forever see a new key, thus it'll keep iterating. Is it possible to make this kind of circular redundancy?


Solution

  • One example of how for..in can fail with untrusted input would be a Proxy object that does something nasty in its ownKeys trap:

    evil = new Proxy({}, {
        ownKeys() {
            console.log('got ya');
            return [];
        }
    });
    
    
    for(x in evil) {
        console.log(x)
    }