- For web, user/pass login exchanged for plain session cookies. Should be marked httpOnly/Secure, and bonus points for SameSite and __Host prefix [1]
- For web, deploy a preloaded Strict-Transport-Security header [2]
- For api clients, use a bearer token. Enforce TLS (either don't listen on port 80, or if someone makes a request over port 80 revoke that token).
- If you go with OpenID/Oauth for client sign-ins then require https callbacks and provide scoped permissions.
- Don't use JWT [3]. Don't use CORS [4].
Again these are broad strokes - if you gave more information you'd get a better response.
[1]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Se...
[2]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/St...
I really like this trick! Not only do you now have a log of "shady stuff" happening, but you've gotten rid of the now compromised tokens instantly!
JWTs as bearer tokens aren't bad in their own right, but if you aren't careful you can screw yourself and therefore many security experts avoid them for use in securing systems. Plus a lot of people mistake it for an encrypted token which it isn't. You can imagine how bad that can get.
Tbh I'm with the parent commenter. I avoid them, but if you avoid common pitfalls they should work for your system no problem.
I'm on mobile and can't be arsed to gather sources, but you can search the claims I made and you'll see several articles about these problems. There's even a defcon talk about a new proposed standard (called Paseto I think) that starts by highlighting the major issues with JOSE and JWT specifically.
As a concrete example: people occasionally misuse the Origin header, thinking that they can use it as a form of client authentication. The idea is that any client request from a non-whitelisted origin will fail. But any user can spoof their own Origin header, and the Origin header is primarily intended to protect users from making CORS requests they didn’t intend (because in most cases an attacker cannot coerce a browser to forge a header).
It is also correct that JWT 1) supports far more cryptography than is necessary; and 2) supports weak cryptography. You can do better than JWT for session management security and performance merely by generating pseudorandom tokens, associating them to sessions and performing lookups.
More generally speaking: signed, stateless tokens are attractive for a variety of technical reasons. They have legitimate uses. But it's typically a poor security decision to choose them in lieu of revocation, for reasons which are mostly uncontroversial among those who work in security.
A JWT token is composed of three parts: a header, payload, and signature.
The problem is that people can put sensitive info in the payload.
None of it is encrypted, it's only signed with HMAC.
Unless you're keeping track of the tokens, once a token is issued it's valid until it expires, due to it's stateless nature.
You can use a JWT as a Bearer token, but since it's only base64 encoded, you can pull out that payload data.
A truly opaque Bearer token will be meaningless to anything other than your server.
Play with the debugger here to see what I'm talking about: https://jwt.io/
Not all bearer tokens have this property.
However, I wouldn't throw other anti-CSRF measures away because if the attacker can use a stored XSS vuln, they can still make their way to a CSRF as well. Besides that, not all browsers support SameSite flag yet.
Why do you think so? I would guess it's a tradeoff about what you think is more likely to happen. XSS or CSRF.
Local storage (and session storage) is vulnerable to XSS. Use a strict content security policy and escape (htmlspecialchars in php and similar functions in other languages) output to combat that.
Cookies are vulnerable to CSRF but can't be read from JS if they are http only (no XSS). To combat CSRF most frameworks already have built-in csrf token support. In case of a API use a double submit cookie. Frameworks like AngularJs/Angular support that out of the box. Also use the secure flag SameSite and __Host prefix [0][1]
[0] https://www.youtube.com/watch?v=2uvrGQEy8i4
[1] the slides from the video: https://www.owasp.org/images/3/32/David_Johansson-Double_Def...
1. The specification has points of ambiguity that have led to a number of flawed implementations. 2. JWT is saddled with unnecessary complexity which also contributes to recurring implementation flaws. 3. JWT increases the complexity of session revocation in contrast to a simple, stateless session ID.
The arguments and counter-arguments are a bit more involved, but be aware that by the time you account for the downsides, you may have negated the value you hoped to gain from stateless web tokens.
If you can use a simple session id, use it. If you need JWT to support external authentication providers, use a short expiration and swap the (fully verified) token for a session id.
Hire an expert.
If you can't answer these questions yourself (which is fine - it's specialized knowledge separate from the skillset needed for building a useful application), you are lacking critical competence for coding anything handling health information.
The security minefield is much much bigger than the login page.
Then I read the last paragraph of the question.
Please follow this guy’s advice. As someone whose medical data you might one day be handling: please get someone who does this well.
Imagine you (or a family member) ever end up sick; your medical data ends up on Pastebin, and the arstechnica article about it surfaces a forum post from the engineer responsible: “hey guys howto auth?”. Honestly: how would you feel?
I agree with your conclusion (especially in a comment down the thread about nurses), and just wanted to add to something you said, because I often come across this sentiment that learning by doing is how professionals become what they are, and wanted to play with that idea. In tech, this sentiment is often reinforced by stories like Elon Musk learning how to build cars and rockets by reading books (which he did, but the truth is more that he surrounded himself with trained professionals who could design and execute). In my mind, to be a trained professional requires:
* conscious practice over a long period of time (in order to see all the variations)
* correct feedback from work, peers or masters (community)
* access to the right tooling and body of knowledge. (guilds, journals, trade secrets)
In many areas of programming, these are achievable by a competent individual working alone, but sometimes these factors aren't there but appear to be, which can lead to false and misleading knowledge. In my own area of numerical mathematics, sometimes newbies try to roll their own linear solver (a seemingly easy exercise), not realizing the full body of research and knowledge there is behind handling corner cases. Also, there are myriad tricks-of-the-trade (guild secrets) that are really hard to learn from just reading code -- but that one can learn from osmosis/word of mouth if one works in a lab or research group. This is why it takes years of doctoral and postdoctoral studies to churn out a good numerical analyst.
The CS analogy would be someone rolling their own database from scratch. In these endeavors, the baseline of knowledge to get started is very low, but the real-world knowledge required to make the product robust needs to be built-up over time and by many competent people (through collaborations/teams/community).
I just wonder if security/auth/crypto products fall into these complexity categories, and perhaps it might not be easy--or indeed possible--to become a professional as an individual (without the right conditions in place), and that it might make sense to "stand on the shoulders of giants" as it were, which was your original point.
There isn't enough information on the question to tell wether the OP is a complete novice with no idea of the minefield he is getting it, or if he is somebody competent that wants a list of current practices to start further research.
Simplicity is also Security
There's value to many in SaaS offerings, but any decently-sized programming ecosystem has a crap ton of auth offerings. e.g. Devise [0], Dotnet Identity [1], Django Auth [2]. Authorization is the fiddly/annoying part. For authentication, a reasonably motivated developer can expect to have workable, secure password authentication going in a couple hours, as long as they don't try to invent their own encryption scheme.
[0]: https://github.com/plataformatec/devise [1]: https://docs.microsoft.com/en-us/aspnet/core/security/authen... [2]: https://docs.djangoproject.com/en/2.1/topics/auth/
OpenID is a mechanism for one website to assert a user's identity to another website. OAuth is a way to let a user delegate access to some of their data on one site to another site. Neither have any particular affinity with the healthcare space, and they are not things you sprinkle on for extra security.
[0] https://www.hhs.gov/hipaa/for-professionals/security/index.h...
That's before the law gets involved as well.
It's definitely not enough alone, but at least gets you going on the security & compliance aspects.
I highly recommend talking to someone who knows HIPAA well.
There is approximately never a good reason for a team to roll their own authentication solution from the base primitives unless that's both their core competency and their product differentiation. It offers virtually no upside for virtually certain downside.
- Your authentication problems are not unique to you;
- The effort of implementing standards (whether it's front end like OAuth, OIDC, or SAML or back end like hashing) is a pain in the butt and easy to make bad choices;
- If your project is successful or as your requirements change over time, now you have to figure out how to add MFA, password resets, internationalization, address security audits, etc, etc.
Doing it yourself means you have 100% responsibility for everything when that is probably not your main skillset or really what you want to spend your time doing anyway.
Disclosure: I work for one of the companies mentioned in this thread.
Good stuff.
Also, I have a question for you, is there a good place to reach you?
Open source OAuth / OpenID connect server
The docs, API and Docker images make it really easy to start developing against. Then the Docker images and database migration tools make it easy to deploy into our production infrastructure.
Also evaluating the other Ory tools like Keto, a policy engine.
The hackability of these is very attractive over closed services like Auth0.
Maybe not the best choice of phrasing
Alternatively you can use the auth code flow baked into lambda; if you have premium support make a case and someone can walk you through it :)
Most advice in the comments is pretty bad though. Stuff like "API Clients need bearer tokens" is completely backwards and pushed by marketing people from companies (Auth0, Okta, ...) that misuse open protocols (OAuth2, OIDC) as a way to legitimize the closed source saas approach they took. Along the lines "if it looks complex it looks secure because most people have no idea". It's actually very easy to use cookies (httpOnly, secure) with API clients and you're saving yourself so much complexity with refreshing tokens and all that stuff.
Yet another possibility for super rapid prototyping is: https://github.com/bitly/oauth2_proxy
edit:// I forgot KeyCloak, but it's also for advanced enterprise use cases (SAML, OIDC, Realms, ...) and (from what I've heard) with a steep learning curve and heavy.
Can you elaborate on how they "misuse" them? I don't have any familiarity with those two companies, generally curious. Thanks.
It's a split between using passwordless logins, or standard password authentication depending on who the target audience is.
I would never in a million years ever think about using a service like auth0. It's not just a huge privacy issue but now a critical component of your app depends on a third party service. Also I know of a few sites who use it and the user experience is really bad. It seems like every other time I access a site that uses it, I have to goto a third party auth0 screen to re-enter my login details (which are already auto-filled out by the browser).
Your user authentication flow is a very unique aspect of your site and it's also one of the first things your users see.
You should have full control over it because if your user's first impression is a slow loading non-intuitive user auth system that bugs them to login every few days they're probably going to look for a competing service. I know I would.
For authorization you are going to have to implement your own solution once you have an authenticated session. What someone can do always depends on your app and the functions you provide and so there is no nice third party solution to this. In my case I store the map of users to roles and what a role can do in a PostgreSQL app and cache there the answers to "which users are in a role" and "what can a role do"... user permission and roles changes are infrequent but flush the cache and so take immediate effect.
As a user performs activities, this may involve a scenario requiring escalation or revocation of authorization roles and corresponding permissions. Invalidate cache at this moment. Lazy cache updated authorization info upon next request.
(I authored Yosai)
It can easily be connected to any API without much "glue". And most common open source services already support it as auth backend.
It's also easier to audit than any custom service you might concoct on your own because auditors already have experience with it through Active Directory.
From there, it's a bearer token encoded in JWT format for ease of debugging. From another NuGet.
We also support username and public key authentication for our SFTP server.
We do support username and password if necessary.
I think this is a rather sweeping, and wrong, generalization.
Though the chattering masses on HN may not be HIPAA devs, that doesn't mean there aren't HIPAA devs here. I'm one of them.
Every time someone brings up an obscure topic on HN, there always seems to be a group of people who specialize in that topic that come out of the woodwork and have fascinating insights.
The largest number of commenters on HN seem to be Googlers, Facebookers, and one man bands. But there are plenty of, for example, Apple devs on HN. They just choose to keep the S/N ratio high.
They have all the upsides of cookies, but also can be narrowed down to be handed to third parties (good for APIs), caveats, and have a standardized and implemented [2] verification scheme.
I wonder why they don't see wider use. Do they have significant downsides?
[1]: http://hackingdistributed.com/2014/05/16/macaroons-are-bette...
If you've got questions about them I'm happy to answer.
any reviews ?
It's a rather large dependency so I won't recommend it for a single project with straight forward auth requirements.
After that we no longer store these details.
We've been using amazon cognito with lambda authorizers.
I will add the following details which are specific for healthcare companies and a bit of inside baseball. Typically people use an email address as the lookup field for a user account. Since email addresses are considered protected health information under HIPAA, I would highly suggest you use usernames instead (possibly auto generated to be safe). HITRUST includes some details about password rules for their certification process. No one will question you if you follow their rules (I think it's 12 characters minimum 1 Upper/Lower/Symbol/Number each). Use a banned password list, you can find one here[0]. You are going to want to set up some manner of 2 factor authentication (I would recommend U2F or TOTP) for all accounts with manual code backup. OAuth and OpenID are goddamn nightmares. You need to own and manage this process entirely by yourself.
Authentication asserts identities. Authorization asserts capabilities. This shifts and compartmentalizes the problem somewhat. Almost all interactive applications need to support robust authentication, but most applications do not require the sophisticated authorization restrictions HIPAA demands.
Whatever it is you choose, you should:
1) Use a mature, reputable library;
2) Use a library which provides the simplest possible interfaces for solving your needs in the most turnkey manner;
3) Engage with a reputable consulting firm specializing in HIPAA compliance and application security.
I would also recommend reading through as much information about Aptible's architecture and design ethos as possible. They have done an excellent job of navigating this problem space.
Beware, authorization is an Alice in Wonderland rabbit hole where one may fall far deeper than one expected to.
A few years ago, I ported Apache Shiro from Java to Python, resulting in The Yosai Project: http://yosaiproject.github.io/yosai
It was a grueling but rewarding experience.
I honored Shiro in name and license, open sourcing everything and using Apache 2. I went even further than Shiro by adding two factor authentication workflow using totp and including starter modules for caching, data store, and integration with the web app I was using (pyramid).
If you choose to use python, or even just want something to learn from and reference, check out Yosai. I put a lot into this work to make it useful for others, entirely on my own.
I spoke with Tobias (podcast init) about the project some time ago: https://www.podcastinit.com/yosai-with-darin-gordon-episode-...
If you use OAuth, anybody can connect using a standard library and "flow" across tons of languages. And you don't need to worry about screwing up the most security critical part of your API. It will save you countless headaches.
Some people bash OAuth because of JWT, but this overblown. Storing permissions in a token is the only sane way to do things if you end up with multiple services down the line (you will).
The whole revocation debate is a bunch of noise about nothing. Make the expiration interval fairly short, and if that isn't enough you can make a cache of revoked tokens that only needs to live as long as your expiration interval. This is still orders of magnitude more efficient than not storing permissions in the token and just as secure.
If you need to revoke all tokens in a breach scenario you just change your signing key. I recommend using SHA256 based signatures rather than public/private key since even though public/private is theoretically more secure, calculating signatures is quite a bit of overhead. If your backend is using a fast language like java/C#/Go, the majority of server CPU will be signing tokens.
Read about OAuth and ignore the haters. The design is well thought-out, secure, and efficient. If it was really that bad you wouldn't see most of the tech giants migrating to and using it. There's a lot of people that don't like it because they don't understand it well enough.
Overall just start with strong security in mind that will meet the U.S. healthcare security rules/laws, even if you aren't in the U.S., the basic principles are just focused around strong security. People can debate the specific methods, but I will argue using almost any third party service has potential problems for you with compliance. Yes, I agree and understand those services specialize around auth usually, and for most companies that is fine and even for some more fringe areas of healthcare that is fine. But take another viewpoint, that is because those companies secure so many disparate third parties their attack surface is huge compared to your own, and a vulnerability at their end may force you to do public disclosures. That alone isn't a sole reason not to use them, but do consider all the factors.
Also, in the U.S. you will likely (depending on specific type of product) need to deal with HIPAA and other similar acts (HITECH/TRUST etc). None of these are actually all that complicated if you take them into account early, although going back and adding them later can be a struggle.
Basic principles is secure everything, have timed (short interval) token expiration, have a global token expunge, and always err on the side of reauth over pass thru. Also, if you have many backend services, do not rely on a proxy authentication service to pass off requests. Force all services to validate the authentication of each request. Yes this is "expensive" in terms of extra cycles but it minimizes the risk considerably. Lastly, store trace and audit logs of everything you can imagine, all requests.
Honestly, authentication is not that hard. There are many ways to do it, all with valid trade offs.
What you need to know is what your AUTHORIZATION story will be. Can anyone who can hit your API receive all data? Otherwise, you either need some kind of stateful access control or some kind of bearer token granting certain kinds of access. If the latter is simple enough for your use-case, then JWT, despite it's naysayers, might shine for you. Otherwise you can just use about anything since you'll be looking up what they can access in a DB anyway.
Considering most EMRs (or at least the ones with which I've interacted) don't go very far beyond a username/password combo, you're probably fine keeping things simple.
Generally, when in doubt, I'd strongly recommend using some existing auth library instead of trying to roll your own. It's not clear where exactly in the healthcare world your site will fit, but if you're aiming for hospitals, any hospital worth their salt is going to be using Active Directory or something similar, so you'll probably want to find something that can support offloading user identification in that direction (and fall back to username/password if the org doesn't yet have AD).
I don't know your specific jurisdiction, but at least in the US, as long as you're encrypting all your data (both at-rest and in-transit) and aren't doing anything egregiously stupid (plaintext passwords, single shared password for everyone, literally selling patient data on the Dark Web, etc.) you should have a pretty hard time violating HIPAA, and you'll already be on-par with most extant medical systems. Any further hardening on the authentication front (e.g. specific session management strategies) will just be icing on the security cake.
If you haven't already, I'd suggest reviewing NIST's guidelines for system security; most official HIPAA reference materials point toward NIST guidelines, and most hospitals will tend toward that direction as well.
The library I've linked brings up a good point to make sure that you know the difference between decoding and verifying the token, but after that it's fairly plain sailing.
[1]: https://jwt.io [2]: https://github.com/auth0/node-jsonwebtoken [3]: https://auth0.com [4]: https://jwt.io/introduction/
We have 10+ web clients, 2 mobile apps and one internet gateway. Spring Security make it very easy to integrate everything.
https://oauth.net/2/ Auth0 is the best documentation to learn about oauth: https://auth0.com/docs/protocols/oauth2
The best part of using Oauth is that you can change your authentication server (UAA, Auth0, etc) without changing your app code (only configurations)
- [0] https://www.robinwieruch.de/complete-firebase-authentication...
- [1] https://www.robinwieruch.de/react-firebase-authorization-rol...
- [2] https://www.robinwieruch.de/graphql-apollo-server-tutorial/
Fullstack JS, Apollo GraphQL, numerous client types, batteries included. Has auth implemented plus a number of other things you will find useful in the graphql world.
If you are in healthcare, you may want to find an auth system like DEX that can talk to several backends like LDAP & Active Directory, as each hospital or institution will likely want to reuse what they currently have implemented. You'll need to hook into them. (This is on our roadmap)
I'm finding it hard to get information above the 'follow these steps to use this library' level, yet beneath 'here's how to make a cryptosystem from scratch'. I'm about to read some RFCs unless I find a better intro resource.
You can choose firebase or AWS Cognito. They offer readymade sever and client SDKs for a wide variety of targets. Firebase is always free, and AWS free for 50,000 users
They offer authorization based on roles
In theory anyone can use it, it works automatically and you don't have to register or anything like that, but I don't know if people are interested in it.
Anyways, when I dabbled a few years back, I uses stormpath but they closed down. Les Hazelwood, the creator or Apache Shiro works at Okta now... Which seems to provide enterprise security.
Can anyone comment on their experience with Shiro, or Okta in general, and if it would help OP.
What I wish is Apple and co would give the consumer choices. I am a low threat target; I don't need to enter a pw to unlock the SIP. So presenting a fingerprint + a hardware key would be a huge security improvement and a reasonable defense against 99.9999999% of the threats I face. Unfortunately, Apple assumes we're all being targeting by physical attacks from the NSA, decreasing my convenience level for a non-existant threat.
Going off your question only, this will also likely end up being the most secure implementation for you (relying on a third party service)
> OIDC
Nooope. Not a good idea. OIDC is pretty damn complicated to implement as a server. And it doesn't help at all with anything around revocation etc. To make that possible, you have to add a load of extra work and you basically lose most of the benefits of using JWTs.
First, as others have said, if you don't know what you're doing on this, you have no business trying to secure health data. Bring in someone who does know what they're doing and then pentest it aggressively.
Second, I'd suggest you'd be better keeping it super simple. Just have a token in a table, refer to the token by its ID and then attach a 32 byte crypto random to it which gets checked before the existence of the token is acknowledged. Compare it with constant timing. If you don't know what that is, again, you shouldn't be doing it with health data - best to learn on a project with less sensitive info.
you need an expert, someone that doesn’t need to ask this question.