17 milliseconds of truth: when your response time answers a question you never asked
Open your login endpoint in a request repeater. Send a username that does not exist, with a wrong password, and note the response time. Send a username that does exist, same wrong password, and note it again. The status codes match. The bodies match. Invalid credentials, both times, because you took the OWASP advice and made your error messages generic years ago. One of those two requests took four times longer than the other, and that gap is the entire vulnerability. This is user enumeration