I need to store password that our users use to connect to third party services (primarily their database). To add complexity to this, the user might be able to add more users later (of course with the same permission levels) so they would be able to connect to those services as well. What would be the best (secure) way to do it?
Storing the hash (and salt) won't be an option since we need to use the password to access to their third party services.
I know there is oAuth option, but their third party service might not have oauth in place. Also not sure if configuring oauth on their database would be that simple.
Another option is to have another system for storing the password (eg. KMS). Encrypt the service's password with the user's own password (master password) so the system can decrypt it later (but not without user's own password).
Something like these:
How do I securely store passwords to a 3rd party webservice in my database?
Security model: log in to third-party site with user's credentials
Is there a better way to do this kind of thing? What would be the security model look like and the checklist to securing it? Or even should I refrain from developing this system at all? Any insight would really be appreciated.
** EDIT **
As some comments suggested, I might be not clear enough on the situation and goals here. So to clarify:
We are trying to build a No-Code feature in which user might be able to connect to third party services holding their data or their own database. Something like Bubble
As for the goals (and threats), we are trying to make the key (password) relatively un-readable (and un-usable) by external threat or even our own developer but our system (with authorisation from the owner) can still use it
Not sure if this is ok to ask here (otherwise just ignore it), but I wonder what kind of method system like Bubble (their database connector plugin) use
The links I showed (and given by gusto2) above recommend the use of HSM, which is costly (even for the cloud solution). Is there a lower cost alternative method?
Apologies in advance for sounding naive but I am new to this and stuck since days to no good.
I have set up LDAP on apache web server using below link and it is working good.
https://httpd.apache.org/docs/2.4/mod/mod_ldap.html
I am able to login to the application using a valid account in the directory. Now I want to create a non-ldap user (common user for API access) that can be allowed access through the web server? Is it possible? How?
I would strongly advise to create API accounts in your Active Directory. (in the company I work for, we use that and call them service accounts)
Centralizing access is the best practice, if you start mixing authentication methods in your application/website it can quickly become a nightmare of spaghetti code to maintain.
Centralizing access also improves security by allowing you to manage access in a single place.
If you do not want to go this way, you have the possibility to create a secondary authentication method through local users that would be stored in a database.
If you go this way, please do not store passwords in a non-encrypted way. Look for the following functions: password_hash and password_verify. When using SQL to transact with your database, make sure you do not end up with SQL injection, it can be disastrous to have SQL Injection in your login script.
I've read several Stack Overflow threads, I still can't decide what is the best option for my case. And the most secure one.
Here is the story. My webapp is to help users automatically get an overview of some of their data available in some third-party website. I need to store for each user some third-party credentials. Each night or so, my server will connect to the third-party services on the users' behalf and retrieve the required data.
Most of those third-party sites do not implement any API or OAuth mechanism, so I was thinking to do some web scraping.
I've read in many places that storing the credentials in the DB is not a good idea - especially because my app needs access to the password (so it has to be encrypted in such a way I can easily reuse it).
So, I have two options left:
Whenever I access (via webscraping) the third-party service, I store on the server the cookies issued by that service, for future reuse. I encrypt them and keep them encrypted in a DB, and decrypt them only when I need them. The problem is that the cookie can be denied or expired after a while, and so the automatic process wouldn't work any more.
I store the credentials in the environment variables. I will be on Node.js and Heroku. That's an idea I found in another SO thread. But I'm wondering about the security of this idea. Is it really safe? No one can access them but me? And what about if I reach many users. Like 1000 users, with 10 services. That's 10000 credentials to store in the env variables. That doesn't seem like a good idea.
I found two interesting questions on Stack Overflow but they don't fit 100% with my use case.
Security model: log in to third-party site with user's credentials (that gave me the idea in point 1)
Rails storing third party credentials.. Anyone know best practice? (gave me the idea in point 2).
I add another answer because maybe this one will do the trick for you.
You said the main goal of your website is to have an overview of third party applications. But what if instead of updating this overview every night, you update it when the user logs in ? It changes everything, because you could use the user's password (of your website) as master password to encrypt (using AES) all the others.
If you do that, the communications between your server and the clients have to be encrypted with SSL pinning, because an attacker could perform a MITM, get the master password and all the others stored in the DB... (Even if in practice it's very hard because you need to hack the client AND the server)
Storing a lot of data that changes and grows in environment variables will never be practical, no matter if it's secure or not so this is pretty much out of the question, unless if you have a small fixed number of users.
Not storing credentials in the database is a very good advice, but the cookies are credentials and even if you store them encrypted, your app needs to be able to encrypt it to use it. (This is unlike the situation with verifying passwords of your users when you don't need to ever encrypt them, you only need to see if the provided passwords hash to the same values that you have stored).
This is a hard problem because to make it work you need to have some form of credentials (whether those are passwords or cookies) stored and ready to be used unencrypted (even if they are stored encrypted, you need to store the keys to encrypt it as well).
Also, what you are trying to do can be illegal. Mayke sure that you follow the TOC of every service that you're using or otherwise you may face legal trouble.
Plan for the attacker gaining admin access to the server. Your site will be very attractive to attackers, kind of a one-stop-shop for user credentials so you will need very good security of the login credentials.
There are more than two options for storing the credentials:
Use an HSM for the storage or individual credential encryption keys.
Keep the credentials on another dedicated server with no Internet access, 2-factor authentication and limit admin personal. Rate limit the access to this server and add rate alarms. Access this server on a per user credential basis over a non-Internet connection. The credentials will only be available to the Internet connected server in memory as used, not at-rest in a file.
Storing users credentials in a reversible way looks like a terrible idea anyway. But if you really want to store them, I suggest you to use the environment variables solution. But you can improve it. To limit the amount of data you store and don't have 1000000 variables as you said, you can just store an AES encryption key, store all credentials in a DB encrypted with this key, and you just have to get this key (which is in memory) and decrypt the DB. But there is another problem with this solution. As I said, this is stored in RAM memory, so it's not persistent, imagine your server has to reboot for X or Y reason... You will lose the AES key and also the credentials of your users... Moreover, if the attacker performs a memory dump, he will have access to the AES key...
I think the better idea is to store the cookies (in an encrypted way) and when this one expires, you alert the user (by mail, phone, notifications, ...) and ask him to fill his credentials again. But it's not a perfect solution ! Indeed the cookies are a type of credentials and shouldn't be stored either...
We are developing a couple of web applications and web services for our intranet. To access resources like databases or other data sources we use technical domain users and store their credentials in the config file of the web apps. Passwords must be encrypted before written to the file. (The application then have to decrypts it to access the resources.)
We do this for quite a while but now a discussion came up. Our server operations team suddenly considers it unsecure to store the passwords in config files because an attacker might successfully decrypt it, maybe by analyzing the little tool used for encryption. (It's written in .Net so indeed it's not really hard to analyse the used algorithm by using Reflector & Co.)
As an alternative they proposed to use the technical user account as app pool security context. But I'm not sure if this doesn't mean to replace one possible security hole by an actual one: If the app pool runs under the context of the domain user, the attacker dont't have to know the password anymore. He simply can use security holes in the application or try to run his own code under this app pool somehow.
What do you mean? Is there a best practice to deal with passwords in web applications?
Thanks,
Rocko
Its a very common practice for a domain user to run the app. Just ensure that account has a really small footprint - only what is needed.
Greetings all:
I currently am building a web application, and have been debating whether to go with a conventional database login system, or going with an openid based login system as we have on stackoverflow and family. What my question is when would an application designer would choose an openid system over the more conventional login system, and when would it be better to use a conventional database login system?
Well it depends on several factors. Some of them are:
Security (is it a critical login like banking system? does the user need to change the password from time to time? logging into my bank account using my facebook account is quite absurd!)
Privacy (dont forget you giving information to openid providers or facebook or google or whatever you port to an synthetic openid)
Dependency on external services (avilability of those in your environment)
Portability (support them once, you have to do it 4ever!)
and the list goes on and on and on.
Generally speaking websites use Single-Sign-On and openid to increase registrations because its convienient for the user.
Permission Control / Oauth etc is another thing.
In my opinion its a very good thing but you should always offter the alternative of a genuine registration.
avoid as many problems as you can. Allow linking of accounts so that the user may change is mind and use his newly acquired openid for his account form now on, or switch to an old school user account.
To sum it up: In the background there ARE in 99% "real oldschool user accounts".
All those openid/connect stuff is just authentication. another way of entering the password.