There is really no reason any developer should try to roll their own auth these days. OWASP has identified and enumerated all of the relevant info. It seems like negligence when a teacher/professor talks about building a web app without referencing the project.
But even if you use a third party, tying identity in to your application almost always still has to be rolled on your own right? So no matter how bulletproof the 3rd party solution, it’s likely that a tremendous number of vulnerabilities on an application basis could come from faulty auth integrations as well
Spoofing. I start up faceb0ok.website or whatever and theme it to look identical to Facebook. I then make a viral Facebook post that tells you Facebook will send you a $50 Amazon gift card if you click on this link. You click, then instinctively log in with your Facebook credentials because you can't tell that you're not on the real Facebook anymore. I now have your credentials.
Man-in-the-Middle (MITM). I'm at the same coffee shop as you and I've taken control of the router. You request your bank's web site and I'm able to route that request through my laptop, fetch the web page, and return it back to you. You log in to the web site. The connection is still encrypted, but the termination of the encryption is actually happening on my laptop. You log into the bank site. I now have your bank account credentials.
Cross-site scripting (XSS). Your site allows visitors to embed content (for example, message board posts) without that content being properly filtered. I use that to embed some JavaScript that watches for users using the log in form on your site and send those credentials to me, or sends the content of the cookie of users already logged on.
Poor hashing. You mentioned that above so you're probably aware of it already, but it's disturbing and surprising how many sites don't have this figured out yet.
I'm not sure what problems network dropouts could cause, at least in terms of security - which is the big problem here.
Of course there's more, but this is what comes to mind. In summary, I strongly suggest you don't try to reinvent a new authentication system. use one already in common use. It's probably already fairly battle-tested and validated for correctness and security. This goes for most other types of software as well.
One that is often not mentioned: cache errors. When systems face scaling issues, caching is often a first line tool. Imagine a bug gets deployed with an off by one error in your cache, or the cache serves the latest entry instead of the right entry.
If you add caching (esp. to your auth-chain), you need automated tests covering every access pattern. Concurrent access, cache timeouts, cache full, cache invalidation, etc.
But folks really cache auth related data? Isn’t that better handled purely through client <> server requests and handling caching for all UI or action based data?
Not at scale. If our auth caching stops, our auth servers can get overloaded at peak times. Granted, horizontal scaling auth is a better first round choice, but caching gives you vertical scaling when you are hitting limits on your database. Another option is z-scaling, but that is really just a way to improve either of the previous two (have different pools of user databases).
Normally I might try to enumerate examples, but I agree with bdibs that OWASP generally holds the canonical text for authentication of web apps.
Alex Stamos, former head of security at Facebook, described the security issues they got as a pyramid where the vast majority of issues were basic fraud, friend/family trust, fake login pages / fake emails, reused credentials, and email takeover. You won’t be able to help with most of these unless you can help your users change their behavior.
For the other stuff, use the best SDLC techniques, never commit secure strings to version control (assume your source repo is misconfigured), use 12 Factor principles, read OWASP docs, search for relevant HackerOne disclosed reports (or blog articles, CTF write ups). There is no amount of coding that can replace red team user testing / a security audit.
As the founder of FusionAuth (https://fusionauth.io), let me relay 5 years of experience in building our platform in bullet points (not exhaustive by any means, but a rough overview). Also note that these aren't all authentication related, but once you build your own authentication, most everything else has to be done by hand as well:
- OAuth 2 IdP and SP federation plus theming
- SAML v2 IdP and SP federation
- Nested federation (i.e. OAuth to SAML to OAuth to another OAuth)
- Consent modeling (CCPA, GDPR, and many more are coming)
- Group management
- Roles and permissions
- All the email things (forgot password, passwordless, email verification, templates, localization)
- Reporting (DAU, MAU, etc)
Every line of code, every API, every HTML page, every button click, every form submit, every layer, every network hop, every operating system, every third-party tool, every library, and every browser must be secured and tested. If you have a big team and a lot of free time, you can probably get something workable that is secure in a year or two.
Of course, YMMV. ;)
Or like other folks have said, you can always use FusionAuth, Keycloak and others. They are all free and do all of this already. Though, I'd be suspicious with some projects. The compliance, auditing and testing pieces are expensive and probably not something they do much of.
And who knows what is going on with IBM and RedHat. I'd run screaming from that disaster if I were you. :)