5 ms·
I too have seen the articles proclaiming that devs should stop implementing auth themselves and instead use some Auth as a service product. After all Authentica
by jaeming 4y ago
I too have seen the articles proclaiming that devs should stop implementing auth themselves and instead use some Auth as a service product. After all Authentication is hard to get right, right? Actually the basics are really easy. Using a short-term JWT and bcrypt to salt passwords is like maybe 10 lines of code. The thing is, most of the truly hard Auth problems I've had to solve in my career took a highly custom approach anyway.
I suspect most people use products like Auth0, not because they are trying to solve those hard problems, but more likely, because it's easy to set up and comforting to hand off that segment to a company that says they are battle-tested and secure, etc.
I personally like writing my own Auth because I can cater to my personal level of paranoia and learn more. Maybe I'm weird in that way, that I like to consider questions like, how short-lived should my token be? Should I issue a new token on every request? Local Storage vs cookie? Should I use a one-time token? Should I store the JWT in memory only on the client? How would I invalidate a user's token at will?
There's lots of interesting questions beyond the basics for sure and I can see how that might be intimidating. Most projects only need the basics though. And if you need more, it might be easier to extend your own implementation rather than some use-case not catered to by a library or service.
At the very least, I think it's wise for dev's to experience writing their own Auth a few times to get a grasp of some the challenges and better understand what those services might be doing for them.
- candiddevmike 4y agoDevs should never default to using JWTs IMO, I think that is leading folks to delegate auth to providers as it overly complicates the process. There's nothing wrong with stateful API keys/session tokens, and I would wager the majority of web services still use them.
- waspight 4y agoJwt is a much easier term to google for information than the api key/session solution you mention. I actually default to jwt just because I don’t have a clear picture of what the alternative is called.
- jaeming 4y agoI agree, stateful sessions can handle a number of problems and use-cases more gracefully. I work with a lot of api's the service multiple clients though and I do see a use-case for stateless as well.
- dewey 4y ago> Using a short-term JWT and bcrypt to salt passwords is like maybe 10 lines of code. You are presenting an extremely limited scope. What you get from using an authentication provider is things like verifying email addresses, OAuth where you just have to "enable" Google, Github, Apple login possibilities. Implementing all these flows yourself is a lot more than 10 lines of code. Then you also have to do password reset flows, resent email confirmation emails etc.
- tppiotrowski 4y agoAlso two-factor auth via email/SMS codes
- x1xx 4y agoalso password policies, account takeover detection/prevention, user device/session list management
- jaeming 4y agoYes, that's why I said "the basics are really easy"? This was not meant to imply 10 lines of code handle the complete user experience workflow around auth. In saying that I have implemented oauth for multiple providers in not too much more lines of code. Maybe like 100.
- vsareto 4y agoHaving your own password table even feels archaic today. From what I've seen, even simple internal apps are doing SSO with a directory provider (Google, AD/ADB2C, Okta, etc.)
- jaeming 4y agoI mean, it's stored in a DB somewhere, even if it's not your own. I would argue your own DB probably has less of an attack vector than major providers.
- mkozlows 4y agoYou didn't mention MFA. You didn't mention SSO. You didn't mention self-serve reset flows. Your approach doesn't work well with mobile apps. These are not rare, exotic things in 2022.
- jaeming 4y agoYeah, that's why I prefaced with "the basics of auth are actually pretty easy". Rather than trying to opt-in to those other auth flows before you need them, I'd suggest starting with the basics and extend as needed. Although the MFA I've implemented was actually pretty easy too.
- tootie 4y agoPersonal story: Someone in the dark past of my company decided rolling their own auth was fine. Our platform is mostly Django so there's a lot of pieces in place OOTB so they thought it would be easy and it probably was. At some point, whatever this auth system was used for just fell off the websites. Some new login features were added back and they used hosted platform for passwords. Enter me, years later, no idea that auth every existed. Eventually we noticed a database table with thousands of users whose passwords were hashed with a now broken algorithm. They were probably sitting there for years and had copies, backups and snapshots wherever.
- jaeming 4y agoI don't quite follow the moral here. Was the Dev who rolled their own auth back when MD5 was the norm supposed to time travel forward to a time when cloud services like Auth and Cognito existed? Or does the fault lie with whoever replaced his auth with cloud services and forgot to drop the passwords table? Most of the security nightmares I've heard of result from laziness or lack of care or someone not seeing a job through to the end. All of the encryption alogos we use will be easily brute-forced at some point in the future. Is it worse to store and back up those hashed passwords locally, rather than trusting Okta to do it for you (which incidentally was breached while your old MD5 hashes probably weren't)?
- tootie 4y agoAuth providers have existed for a long time. And the point is that when you pay a vendor who does nothing but auth, they will be able to mitigate all the changes in the industry and (if you put it in your contract) be liable for damages from a breach. The also have up to date controls in place for protecting user data and likely go through external auditing. Give our org's limited resources we don't have audit trails on a lot of things and the reality that any number of past employees could have exfiltrated data and we'd have absolutely no way of knowing. Okta had a small breach which they disclosed that didn't seem to leak passwords, and if they did I'm sure they have controls in place to expire anything that may have been compromised. Hashing passwords is easy. Mitigating an attack is really, really, really hard.
- likortera 4y agoRecommending people that don't know how to/if to do it (that's why they are asking) to write their own auth, trivializing the problem and in the same comment recommending using JWT terrifies me quite a lot.
- jaeming 4y agoThere's nothing wrong with JWT as a token spec. I prefer stateful sessions as well but but a stateless token also serves specific use-cases. It has also become a standard practice for decouple front-ends that live on different domains, etc.
- dickhardt 4y agoThe identity federation protocol flows are pretty straight forward (I may be biased!) ... but you should use existing libraries for all the crypto. Defeating credential stuffing attacks is HARD. That is where services such as Auth0 shine.
- jaeming 4y agoExisting crypto libs like bcrypt, which I mentioned? Or are you talking about something more? The credential stuffing mention you make makes me think you must mean something more. Does Auth0 by default advise users that they are using breached emails/passwords? If that is default behavior then I agree it does add a shining point to their feature-set.
- dickhardt 4y agoExisting libs for JWTs and PKCE Minimizing a credential stuffing attack requires detecting the attack and then adding captchas or other bot mitigation techniques.
- jaeming 4y agocaptcha integration is super easy and doesn't require a full auth integration service. Detecting a brute-force maybe less so maybe, though I get a lot of DDOS pretection for free with AWS & cloudfront. But I was more interested in the idea of letting users know they were trying to use a breached email/password on register or login. I've got that on bitwarden (password manager), though now days I just auto-generate any password.
- WorldMaker 4y agoThere's an old adage: If you think auth is easy to write, you probably don't know auth. I obviously don't know how much it compares to your specific case, but as general advice it's often good advice when phrased less antagonistically: don't roll it yourself because the rabbit hole is deeper than you expect. On that front, you may think you are paranoid enough, but keep in mind that the service products sometimes have a multiplier effect in play: N developers of various levels of paranoia, M people in various ops/InfoSec/auditing roles, X committees/layers designed to minimize corporate security risk. If auth isn't your job and isn't your core competency, many times it is worth asking if following the rabbit down the hole is worth the time you could save outsourcing to a multiplier effect of a team that focuses 100% on those tasks. As with most "buy versus build" discussions, it's not just about "comfort" but leveraging those multiplier effects. Can you pay someone else for the years of experience and "rabbit hole wandering" and multiple layers of security audits? Auth is a "must have" feature for most products but in and of itself is mostly a security liability and mostly pure overhead: no customer is paying you directly for your auth features, auth is the annoying hurdle to features that they do care about and will pay you for. All that time spent on auth and auth security audits rarely appear to provide good returns on investment for your product and your customers. Time spent on auth is time wasted from user-facing features.
- jaeming 4y agoI've never head that adage. I did hear one from Miles Davis that says, "If you have to ask, you'll never know." I ask a lot of questions though so I never paid much attention to old adages I guess. If auth isn't your job and isn't your core competency I'd argue, it sort of is a core part of any web dev's job and any who neglect diving into it do so at their own risk. Maybe I come from a different time or place than what's the contemporary norm, though I'm okay with that. The main issue I have is with company-sponsored blogs and comments that will just blanket state you should never roll your own auth (because you can pay us instead, oh and btw, we rolled our own auth so you don't have to).
- WorldMaker 4y agoI can understand skepticism with company-sponsored blogs. For what it is worth, I don't have a product to sell here in this space and make no commissions. As a user, I subscribe to haveibeenpwned alerts on my main email addresses and have been for multiple years. I think there are fewer humbling "[hackers leaking my users table] won't happen to me" reminders than that. It happens to everyone. The ones listed in haveibeenpwned are just the tip of the iceberg and the ones we know about and have been confirmed/verified. As an enterprise developer, I've been a part of some of the worst security audits imaginable. Thankfully those were all preventative industry requirements, and I'd hate to have to deal with "the real thing". Those audits always come with a reminder: the most secure data is data that you don't have, anything else it doesn't matter how well you think it is encrypted at rest is a liability. As a user I never want to have to setup another password ever again. I realize that's a pipe dream and we are still at least a few standards away from making that dream a reality, but I believe in it and I've championed it when I've thought standards got close. (I was a fan of the original, now dead OpenID [but not the Zombie OIDC wearing its skin]. I thought Mozilla's Persona/BrowserID was brilliant and killed too early in its infancy. I'm hopeful for Webauthn.) As a developer I never want to own another database table with passwords stored in it. It's low hanging fruit that every attacker is looking for. I don't care at this point how those passwords are salted, hashed, encrypted, mashed, or other waffle house preparation keywords. Attackers still try to pull the records no matter how safe you think they are. Not having them at all is just entirely easier than worrying about having them. I don't entirely care how I get rid of the password table. I've paid for solutions. I've used passwordless tools like "magic links". (To use those right you often need all the hard lessons of JWTs and other token types and keeping those secure. It's not necessarily "easier" or "harder", but a lot of knowing how to do it right transfers.) I just believe pretty strongly at this point that the best password table is one that you don't have and don't have to manage. No matter how easy it seems to "just bcrypt it".
- rtev 4y agoIn your “should I..”s, you mention implementing multiple insecure approaches. If you’re implementing sessions tied to localstorage, your application has a medium severity vulnerability. If you’re improperly invalidating, that’s yet another medium severity vulnerability. The problem is, you’ll slip up here and there. The experts recommend not rolling your own for a reason; little mistakes and gotchas like the details in your post can lead to significant compromise.
- jaeming 4y agoI didn't advocate for storing your session in local storage. I posed it as a question.
- floppydiskette 4y agoThe only time I think it’s okay is with PKCE.
- jaeming 4y agoI mean, yeah, sure. Or for a number of other use-cases. I'd argue the best way is for the client to keep the token in memory over local storage. Of course if you have a tightly coupled app, session-based secure cookie is the best.
- rtev 4y agoI may be misunderstanding you, but I do want to reiterate: if it’s in localstorage, I will hijack user sessions on your pentest. If there’s a use case to keep session tokens in localstorage, it’s insecure design that’s inherently vulnerable.
- jaeming 4y agoWhat I mean by tightly coupled, is if you can have your Frontend and Backend on the same domain, then yes by all means an httpOnly cookie is ideal. Now days there are a lot of SPA's that don't do that, or that have multiple api services across domains, or you are only writing a front-end and using some backend as a service like AWS amplify or numerous other scenarios that have led us to the concept of stateless authentication. You can still use a cookie in those situations, albeit without the use of httpOnly, which means they are going to be just as vulnerable to XSS as local storage. This is why I mentioned keeping a token in memory (this can be made even more secure with web workers). But since this doesn't persist across reloads, it's not an ideal solution for most leading towards utilizing strategies using refresh tokens/one-time use tokens, etc.
- heliodor 4y agoNot implementing it yourself does not imply that you should use auth-as-a-service. There are plenty of auth libraries out there for your programming language of choice. Take a look at their source code and see how much stuff is in there to get a sense of why you should not implement your own. I use django-allauth: https://github.com/pennersr/django-allauth https://github.com/pennersr/django-allauth
- jaeming 4y agoOh yeah, for sure, there are a really good libs. Someone mentioned passport. I've personally used Devise/warden in Rails. Though we had to monkey patch/extend it so much that 6 years later it was almost a different beast entirely. But I'd still argue it's worth knowing what those libs are doing for you and you can only really appreciate it once you've rolled your own. I've done so on many a personal project where the risk was low. But yeah honestly, if I was rolling a large-scale enterprise app today, I'd probably utilize AWS Cognito. But this is also not for the faint of heart IMO.
- Fire-Dragon-DoL 4y agoThe authentication portion of devise is actually really small!
- kanonieer 4y ago> I too have seen the articles proclaiming that devs should stop implementing auth themselves > and instead use some Auth as a service product. It's a moved goal post which sneakily tries to position itself on top of the old adage "never roll your own crypto". Problem is, that adage is really about security whereas "don't roll your own auth" is about not wanting to do a mostly boring part of your job. I'd take my hat off if they'd admit it, but it's much easier to get budget with potential security scares compared to "we don't wanna".
- jaeming 4y agoToo true and worthy of a rant of all it's own...