๐ฌ HTB CTF: CandyVault โ NoSQL Login Bypass
ุจุณู ุงููู ุงูุฑุญู ู ุงูุฑุญูู
HTB CTF: CandyVault โ NoSQL Login Bypass
๐
Date: October 12, 2023
๐ฏ Difficulty: VERY EASY
๐จโ๐ป Author: 0xAzoz
๐ Category: Web, Authentication Bypass
Quick Summary:
This was a fun and clean NoSQL injection challenge the idea was simple: break the login form using MongoDB quirks and grab the flag. No need to overcomplicate it just understanding the logic behind the query was enough to break it.
Recon & First Look:
When I loaded the target, it was just a basic login page โ no register, nothing else to poke.
Looking at the code (they gave us the source code in ./challenge/application/app.py
), I spotted how the login logic works. Here's the juicy part:
@app.route("/login", methods=["POST"])
def login():
content_type = request.headers.get("Content-Type")
if content_type == "application/x-www-form-urlencoded":
email = request.form.get("email")
password = request.form.get("password")
elif content_type == "application/json":
data = request.get_json()
email = data.get("email")
password = data.get("password")
else:
return jsonify({"error": "Unsupported Content-Type"}), 400
user = users_collection.find_one({"email": email, "password": password})
if user:
return render_template("candy.html", flag=open("flag.txt").read())
else:
return redirect("/")
Focus on This Line:
user = users_collection.find_one({"email": email, "password": password})
We can see here that:
- it's just querying MongoDB directly using user input. No sanitization. Nothing.
- So? itโs a NoSQL injection waiting to be exploited.
The Vulnerability:
In MongoDB, The find_one()
function is used with a filter directly built from user-controlled input (email
and password
) without applying any sanitization or validation. This creates a classic NoSQL injection vulnerability.
So instead of passing:
{
"email": "admin@vault.htb",
"password": "password123"
}
We just passed:
{
"email": { "$ne": 0 },
"password": { "$ne": 0 }
}
The $ne
operator is used to bypass the authentication process. With the following query, the user will be able to access the first account in the database, without needing to know any valid identifiers
That basically means:
โGive me any user whose email is not 0 and password is not 0 Itโs a logic operator, like != in SQL.โ
MongoDB goes, โsure,โ returns the first user in the DB (which of course not zero) โ and boom! Logged in.
I got redirected to candy.html with the flag printed at the top
Lessons:
-
NoSQL injections are still relevant, especially in apps using MongoDB with poor validation.
-
Always check if the API accepts JSON payloads โ that's usually where the magic happens.
-
You donโt need big tools for these โ just Burp and logic.
References:
- HTB CandyVault Official Challenge Page
- MongoDB NoSQL Injection Cheatsheet
- What is NoSQL Injection? Exploitations and Security Best Practices