User enumeration: how your API reveals who your customers are
A leak that doesn't look like a leak
No data is stolen, no database is breached. Yet a competitor or attacker can learn: which companies use your SaaS, how many employees they manage, and which work email addresses exist at each one. That's enumeration, and it flies under the radar because it only exploits "normal" behaviors of your API.
For an HR SaaS it's doubly sensitive: your customer list is your commercial asset, and a client's employee list is the perfect starting point for a targeted phishing campaign ("your payslip is available").
The 4 classic vectors
Differentiated error messages
Login: "incorrect password" vs "unknown user". Sign-up: "this address is already in use". Inviting a colleague: "this user belongs to another organization". Every differentiated message is an oracle confirming or denying that an account exists.
Sequential IDs
GET /api/companies/1847 returns 403, GET /api/companies/1848 returns 404. The 403 says "exists but not yours", the 404 says "doesn't exist". Iterate, and you've counted your customers — and their month-by-month growth if IDs are chronological. Use UUIDs, and return 404 in both cases.
Response timing
Even with identical messages, if password verification (bcrypt, ~100 ms) only happens when the user exists, the latency difference is enough. Perform a dummy hash when the account doesn't exist.
The forgotten side endpoints
Login is often protected, but not: the password reset request, the email-availability check at sign-up, adding a member to a team, the user search field. The attacker uses the chattiest link in the chain.
Rate limiting: necessary but not sufficient
Without rate limiting, enumeration runs at thousands of requests per minute. But IP-based limits alone no longer cut it: attackers rotate through thousands of rented residential IPs. Combine:
Checklist
Our API audit systematically tests these vectors in real-world conditions — they're often the first thing automated scanners miss.
Go further
Related articles
Three adjacent analyses to keep exploring the same attack surface.
JWT token management in HR SaaS: pitfalls to avoid
JSON Web Tokens are everywhere in modern SaaS. But poor expiration and rotation management can compromise your entire application.
GraphQL API: 6 vulnerabilities that scanners don't detect
Introspection enabled, depth attacks, batching, IDOR via relay IDs — GraphQL flaws invisible to automated tools.
Silae, PayFit, Lucca APIs: where to look at integration security
Payroll and HR integrations often create their own exposure surface: secrets, webhooks, identity mapping, and logs.
Sources
Related services
If this topic maps to a real risk in your stack, these are the most relevant CleanIssue audits.