this post was submitted on 25 Sep 2023
32 points (92.1% liked)

Programming

17540 readers
64 users here now

Welcome to the main community in programming.dev! Feel free to post anything relating to programming here!

Cross posting is strongly encouraged in the instance. If you feel your post or another person's post makes sense in another community cross post into it.

Hope you enjoy the instance!

Rules

Rules

  • Follow the programming.dev instance rules
  • Keep content related to programming in some way
  • If you're posting long videos try to add in some form of tldr for those who don't want to watch videos

Wormhole

Follow the wormhole through a path of communities [email protected]



founded 2 years ago
MODERATORS
 

In an API I have there's a requirement to use an authentication method other than OAuth2 or any kind of token generation which requires making an extra HTTP call.

With this in mind there's this https://www.xml.com/pub/a/2003/12/17/dive.html
I've only stored passwords as hashes and used functions like password_verify to know the user sent the proper credentials without actually knowing the password stored in DB.
WSSE requires to encrypt with SHA1 the credentials being sent, which means the API needs to retrieve the password in plain text to recreate the digest and compare it to the one sent by the user.
So, how should I be storing this password if the code needs it to recreate the hash?
Should I have something like a master password and store them encrypted instead of hashed?


Most of the information I've found about WSSE is very very old, and some implementations have it marked as deprecated, do you know any other type of standard authentication where the user can generate the token instead of having to make an extra HTTP call?

you are viewing a single comment's thread
view the rest of the comments
[–] [email protected] 7 points 1 year ago* (last edited 1 year ago) (1 children)

Neat. I can help with some of these concepts:

  • WSSE is just a reimplantation of Basic Auth, but it has a dramatically worse security posture today, than Basic Auth. WSSE is complex and deprectaed. Basic Auth is not wonderful, but is simple and is still being patched.
  • On that note, Basic Auth is almost certainly what you want here.
  • Don't use cleartext for any of this (obviously). It need HTTPS or it'll get owned immediately.
  • Don't do an extra encryption step inside your HTTPS connection. HTTPS isn't perfect security, but if a job doesn't call for OAuth and token rotation, it also probably also doesn't call for a needless extra layer of encryption on the wire.
  • Do encrypt your data at rest.
  • None of your source code should be doing any kind of encrytion.
  • Encryption on the wire should be via HTTPS.
  • Encrytion in storage (at rest) should be via a database or disk drive setting.
  • There's no benefit to encrytping data that has already been encrypted, and there's real risks of accidentally ruining the protection of the original encryption. But mostly, additional encryption just makes life hard for your ops team while adding zero security value.

You can protect your Basic Auth password simply by storing it in cleartext where it is needed with reasonable protections

(This is again assuming your use case is actually okay for not having OAuth. If it's health data, suck it up and do real OAuth, obviously.)

Reasonable protections for your Basic Auth passwords:

  • Make sure nobody except your administration team can read the file where it is stored.
  • Have separate basic Auth passwords for every service and client. No one wants one compromised password compromising everything. This happens all the time and it's not pretty.
  • Don't ship it around your network for fun. If you have access to AWS secrets, Hashi Vault or Azure Secrets, put it there and check it out as runtime. Otherwise, just put it where it needs to be and don't try to be clever about it.
  • Don't check passwords into source control. It ends up being another avenue to accidentally share them.

In summary:

  • Use basic Auth.
  • write the password in plain text in a correctly secured file exactly where it's needed.
  • for the love of all that's holy, don't try to use WSSE.
  • use HTTPS.

Happy sailing!

Edit: Also, practice replacing the secret, ideally with automation - and preferrably do so every 90 days.

Edit 2: Make that password as long as heck and meaningless. No one needs to memorize this thing. Generate it random, long and meaningless, paste it in two places, and forget about it for 90 days.

Edit 3: Deliver this secret to your end user over the phone (spoken to a human, not a text message). Do so every 90 days. When they complain, ask them if they're interested in OAuth now.

[–] [email protected] 1 points 1 year ago (1 children)

Thanks for all the information and advises!

So in theory basic auth is enough when sent through HTTPS, right?
If this is the case then the user would need to handle their password and my API can keep storing just the hash.

In another comment JWT was suggested, maybe this could also be a solution?
I'm thinking the user can worry about generating and signing the token and we could only be storing the public key , which requires less strictness when handling it, this way we can validate the token has been signed by who we expect and the user will worry about the private key.

[–] [email protected] 2 points 1 year ago

So in theory basic auth is enough when sent through HTTPS, right?

Yes. Don't put nuclear weapons, health data or huge sums of money behind it, but basic Auth has been doing a fine job for a lot of things for a long time, and HTTPS is a complete solution (until the next time it gets owned).

If this is the case then the user would need to handle their password and my API can keep storing just the hash.

Yep. The hard part is securely delivering the generated secret to them. And making sure that, the shorter and less random that secret is, the more often it gets replaced. For a lot of not-too-sensitive use cases, a phone call and a long random secret will do the job.

In another comment JWT was suggested, maybe this could also be a solution?

JWT is a fantastic solution, and probably the first thing you want to upgrade to if your use case needs more than Basic Auth.

I'm thinking the user can worry about generating and signing the token and we could only be storing the public key , which requires less strictness when handling it, this way we can validate the token has been signed by who we expect and the user will worry about the private key.

That makes sense. Note that many popular JWT libraries will do a lot of that for you.