WIZER CTF #16: COMPANIES API

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 #16

Goal

In this challenge, we're identifying a simple scenario of a NoSQL Injection (a.k.a. NoSQLi). Let's take a look!

Description of code

The code below introduces a simple company retrieval endpoint. The author took the time to validate that the query argument, which is a user input, does not include keywords of operators which could cause an unintended retrieval of records.

chal16-code1

What’s wrong with that approach?

In reviewing the validation method isValid(), the author did cover almost all of the "dangerous" operators which could cause a NoSQLi. However, there's one operator that slipped and could still be used which is the $regex operator, and it's powerful enough to provide the requested outcome and cause a NoSQLi.

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

This is a simple case of bypass which is caused by missing a crack even-though the developer was apparently aware of the risk. The $regex could be used to generalize the query and fetch all the companies at once, overriding the intended behavior. A typical override could look like { "$regex": "[\\s\\S]*" }, a nested operator provided as the `company_id` value.

So what?

NoSQLi is a little less commonly known by developers. It is not less risky than its older brother SQLi (a.k.a. SQL Injection). The risks attached with a NoSQLi vulnerability, start with unauthorized access to data, but could get to gaining full control over a system, connecting as super-admin etc.

Main Takeaways:

  • Avoid making up your own Sanitizations and Validations:
    Always use a well-known library or a framework to handle the input validation. In this case, the developer tried to validate the input by himself, and missed a critical operator. If you cannot find any suitable library you can use, then the second best approach is to prevent the source of the issue and validate the value against a required pattern. In this case, the developer could have blocked nested operators altogether by validating the `company_id` input value and making sure it's of the required format (UUID in this case). See the following example:

    chal_16_match_pattern

  • Always prefer an allow-list over a deny-list:
    In our little example, the developer has used a deny-list approach to validate the input, with that approach one has to manually find all the potentially harmful values and deny them one-by-one. This is a very risky approach, as you could miss a critical value. The allow-list approach is the opposite, you'd have to allow only the values which are safe and deny the rest. This is a much safer approach, as you can start with the obvious valid values you know of, and expand the list as needed, assuming you identify additional required valid options in the future.

 

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

CODE WIZER!

Past Challenges

CTFs For Developers