0

I have a SaaS application in which users can connect their RDBMS (postgres, mysql etc) and query data from it. I'm wondering what's the best practice to keep their connection details safe. Currently, I'm saving them to my application db (postgres) in plain text.

Maybe I can encrypt them?

Eventually, I'd like to achieve SOC2 compliance too.

6
  • 2
    These users have their DB exposed to the public Internet? scared Commented May 18, 2023 at 9:49
  • I didn't mention anything about a public internet.The SaaS application can be used on the public internet or deployed on-premise/self-hosted for additional security/compliance. In any case, the question is valid. That's how BI tools work. Look at Metabase for an example. I don't know why this is down-voted. I want to know how to save passwords like this? I know all database exploration tools do this. Commented May 18, 2023 at 10:14
  • As other have said this is a hard and complex problem. But it's not a very obscure one - you can just search "online password manager" and learn about what tools like 1Password, Bitwardern, Lastpass, Nordpass etc do. You're unlikely to be able to implement the same level of security they do. Commented May 18, 2023 at 17:07
  • "SaaS application in which users can connect their RDBMS" - so users connect to a different RDBMS which is not part of the SaaS application and need to enter their own credentials? That's what you wrote, and that is the question Christopher answered. From the comment below his answer, however, I guess you meant something different. Commented May 23, 2023 at 3:35
  • @bdsi online password managers are interactive tools, which require user input to work. They are not applicable in background processing scenario. Commented Feb 13, 2024 at 12:50

2 Answers 2

1

Well, this a complicated and fascinating subject, Secret Management. Consider secrets to be any type of credential: usernames and passwords, keys, tokens, AES keys, MFA seeds, or the 12 (recovery) words of crypto wallets and, why not, connections strings too.

Try keeping this data secure for 99% of its lifetime.

  • at-rest: Wherever it's stored, it should never be in plain text format.
  • in-transit: Whenever it's transferred, it should never be in raw format.
  • in-memory: Whenever it's loaded into memory, it should never be vulnerable to profilers

In this specific case, the first thing to do ASAP is encrypt the credentials.

@Christophe's answer suggests the well-known pattern of comparing hashes instead of credentials in raw format. The problem is that hashes are not reversible. We lose the credentials, hence the capacity to create new connection strings.

Consider PosgreSQL's built-in encryption capabilities. They support at-rest and in transit encryption.

As for the in-memory security. The techniques depend on the stack, but some are quite generic. For example: don't store secrets in immutable types, nullify variables referencing secrets, or don't retain secrets in memory longer than necessary (no caches).

-2

Never ever store passwords in plaintext, because :

A better way of managing passwords is to avoid knowing them:

  • calculate a hash code with an algorithm of cryptographic quality
  • store the hash code in the database
  • to authenticate a user, compute the hash code of the entered password and compare it to the hash code in the database
  • prefer salted hash-codes.

OWASP guidance recommends to prefer having over simple encryption, because the possibility to decrypt does not prevent the risk of leakage.

If you need to use the password to establish a connection to third party on behalf of your users (and the users accept to record their password in your service and allow you to use it), then the hash code will not work and you'll indeed need to encrypt. To avoid being a source of weakness, you could however consider using some token based authentication, e.g. OAuth 2 which allows the user to establish the authorisation without you having to store any passwords.

6
  • 3
    No you don't understand the context. That's for user authentication. I use django for that, it's already handled. I'm referring to credentials for access to databases like postgres/mysql. Those services expect passwords in plaintext afaik. Please correct me if I'm wrong. I'd love to hash the password. These are generic facts I obviously know. Commented May 18, 2023 at 10:59
  • @AvinKavish I think it's worth to edit the question to make the problem clearer. Meanwhile, I've added a paragraph about this case. Keep in mind that storing the passwords encrypted is better, but makes your system a source of weakness (e.g. if encryption keys are leaked, if some new 0 days expose memory used for decryption as in heartbleed. Commented May 18, 2023 at 11:35
  • @AvinKavish: you need to enable encryption-in-transit for you database connectivity. That means an encrypted connection is established first before credentials are exchanged over that encrypted connection. Commented May 18, 2023 at 14:35
  • Even if the application is deployed on premise. It would be good to understand the zero trust security model. Commented May 18, 2023 at 14:38
  • 1
    "I'm referring to credentials for access to databases like postgres/mysql." Why do you need to store these credentials outside of the database's internal credential store? Commented May 18, 2023 at 21:11

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.