10
\$\begingroup\$

This is a program I wrote in JavaScript to validate some inputted credentials, with an intentional vulnerability. The credentials_validator function takes an object as input, with usernames and passwords. It returns a function, which takes a username and password and returns true if the credentials are valid.

Your challenge is to find a username and password which, when passed to the function returned by credentials_validator, cause it to return true without knowledge of the credentials ahead of time.

This is a , so the first valid answer wins.

Program:

var credentials_validator = (credentials) => {
    if (typeof credentials !== "object")
        throw new TypeError("'credentials' must be an object");
    
    for (var username in credentials)
        if (typeof credentials[username] === "object")
            throw new TypeError("Passwords may not be objects or 'null'");
    
    return (username, password) => {
        if (typeof password === "object")
            throw new TypeError("Passwords may not be objects or 'null'");
        
        if (!(username in credentials))
            return false;
        
        if (credentials[username] === password)
            return true;
        
        return false;
    };
};

/*

Run with:

    var validator = credentials_validator({
        "J. Doe": "P4ssword",
        "R. Wolf": "1234",
        "X. Ample": "wxyz#1"
    });

    validator("J. Doe", "P4ssword"); // true
    validator("R. Wolf", "123"); // false

*/
\$\endgroup\$
3
  • \$\begingroup\$ I'm not sure if the difficulty of this challenge is too low. Couldn't sandbox it for obvious reasons :p \$\endgroup\$ Apr 26, 2021 at 18:31
  • 1
    \$\begingroup\$ Suggested test case: var validator = credentials_validator(Object.create(null));. Not sure if this is intended to be a valid input or not but the existing answer doesn't work for it. \$\endgroup\$
    – Etheryte
    Apr 26, 2021 at 20:56
  • \$\begingroup\$ @Etheryte I didn't mention this in the question because I didn't think about it, but assume the property names and values are within reason. The credentials object will just be ordinary names and passwords, not {} or null or { "isNaN": () => true }. \$\endgroup\$ Apr 26, 2021 at 22:29

1 Answer 1

6
\$\begingroup\$

username = 'toString', password = {}.toString

Try it online!

Note: Due to a certain username pointed out by Wezl in the comments, this answer is not valid for the current challenge.

Why this works:

Among other properties, Object.prototype.toString is inherited from Object.prototype, even if it wasn't a part of the object literal given to the validator. Since any object inherits the same function {}.toString is the same as the toString of the credentials object.

\$\endgroup\$
9
  • 3
    \$\begingroup\$ Well that was fast :p \$\endgroup\$ Apr 26, 2021 at 18:41
  • 3
    \$\begingroup\$ What about var v = credentials_validator({ "toString": "purple" }); v("toString", {}.toString)? \$\endgroup\$
    – Wezl
    Apr 26, 2021 at 18:47
  • 1
    \$\begingroup\$ valueOf is a shorter crack :-p \$\endgroup\$
    – Arnauld
    Apr 26, 2021 at 19:00
  • 1
    \$\begingroup\$ "this answer is not valid for the current challenge" -- Isn't this the one that was intended by the OP? \$\endgroup\$
    – Jonah
    Apr 26, 2021 at 19:20
  • 1
    \$\begingroup\$ @Wezl You may still define your own Object.prototype methods using a newly created Symbol to make sure no such username may ever exist. But I'm not sure if define some newly created attributes is allowed here. \$\endgroup\$
    – tsh
    Apr 27, 2021 at 2:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.