Options for Securing Connection Strings - security

Just a general architecture question.
I know that for web sites, one can use the features built in to IIS to encrypt the connection string section. However, what I am not certain of is this... If I do this and then copy the web.config to another project, will the new project still be able to decrypt the connection strings section in the config file?
Where this becomes an issue is production database access. We don't want anyone to be able to copy the config file from production into their project and have carte blanche access to the production database.
Currently the way my company does it is to store the encrypted connection string in the registry of the server, then use a home-grown tool to read the registry and decrypt the value on the fly. This prevents someone from just looking into the registry or web config to see the connection string.
Further, for thick client (WinForms, WPF, etc.) applications, this could be a little more problematic because once again, I am unsure if the IIS encryption trick will work since the applications would not be running on IIS. We currently have a kludgy solution for this which involved the same home-grown application, but reading the encrypted string from a binary file and decrypting on the fly.
It just seems very patched together, and we are looking for a better way to do it (i.e., industry standard, current technology, etc.)
So, a more general question is this...
What approaches have you used for securing your connection strings? Especially when it comes to multiple application types accessing it, encryption, etc.

A quick Google search will show you other people's attempts at encrypting some or all of an application configuration file (i.e. Google "ecnrypting application configuration files").
But more often than not, I find that the better answer is properly securing the resource that you are concerned about (usually a database). Windows authentication is always preferred of SQL authentication, that way passwords do not need to be stored in the config file, though this may not always be an option. If you want to prevent access to a resource (especially if it's usually accessed through any sort of web layer, like a web service or a website itself), then host the resource on a different server (which is preferred anyways) and don't allow access to it from outside your internal network. If the attacker has access to your internal network, then there's usually bigger concerns than this one resource you are trying to protect.
If you are concerned about a malicious person performing an action that even your application can't perform (like dropping a database), then ensure that the credentials the application is using doesn't have that type of permission either. This obviously doesn't prevent an attack, but it can reduce the amount of damage that is done from it.
Securing information stored in a configuration file that is located on the user's machine is generally not worth the time, IMHO. At the end of the day, the machine itself will need to be able to decrypt the information, and if the machine has the means to do it, then so does the user. You can make it hard for the user to do it, but it's usually still doable.
This isn't really a direct answer to your question, but I hope it gets you thinking down a different path that may lead to an acceptable solution.

From my understanding the protection of encrypted connection strings as for example presented in the article Importing and Exporting Protected Configuration RSA Key Containers protected the connection string on a user-level.
This means that only the account running IIS (NT AUTHORITY\NETWORK SERVICE) can access the cryptographic keys for decrypting the connection string. Therefore this protected only against users who are able to log-on onto the server holding the web.config file. But it can be extended to limit access to certain application.
Regarding the fat client there may be a way to narrow down the interface a bit:
Define all SQL commands as stored procedures on the server and change the settings for the used user account to only allow executing those stored procedures. This would limit access to the database to operations that can be performed using the SQL login credentials.

I would use the SQL DB account management features, with specific permissions only (e.g. at it's most abstract - allow the execution of read only SQL commands) and only from allowed hosts and/or realms.

Related

What is the risk of hardcoded credentials in creating database connection?

Hi security aware people,
I have recently scanned my application with a tool for static code analysis and one of the high severity findings is a hardcoded username and password for creating a connection:
dm.getConnection(databaseUrl,"server","revres");
Why does the scanner think this is a risk for the application? I can see some downsides such as not being able to change the password easily if it's compromised. Theoretically someone could reverse-engineer the binaries to learn the credentials. But I don't see the advantage of storing the credentials in a config file, where they are easy to locate and read, unless they are encrypted. And if I encrypt them, I will be solving the same problem with the encryption key...
Are there any more risks that I cannot see? Or should I use a completely different approach?
Thank you very much.
A fixed password embedded in the code will be the same for every installation, and accessible by anyone with access to the source code or binary (including the installation media).
A password read from a file can be different for each installation, and known only to those who can read the password file.
Typically, your installer will generate a unique password per site, and write that securely to the file to be read by your application. (By "securely", I mean using O_CREAT|O_EXCL to prevent symlink attacks, and with a correct selection of file location and permissions before anyone else can open it).
This is an interesting one, I can give you examples for a .Net application (as you haven't specified running environment / technologies used). Although my guess is Java? I hope this is still relevant and helps you.
My main advice would be to read this article and go from there: Protecting Connection information - MSDN
Here is a page that describes working with encrypted configuration files here
I've seen this solved both using encrypted configuration files and windows authentication. I think that running your application as a user that will be granted access to the relevant stored procedures etc (as little as possible, e.g. Principle of Least Privilege) and furthermore folder access etc is a good route.
I would recommend using both techniques because then you can give relevant local folder access to the pool for IIS and split out your user access in SQL etc. This also makes for better auditing!
This depends on your application needs though. The main reason to make this configurable via a config file or environmental user account I would say is so that when you come to publish your application to production, your developers do not need access to the production user account information and instead can just work with Local / System test / UAT credentials instead.
And of course they are not stored in plain text in your source control checkin then either, which if you host in a private distributed network like GIT could mean that this could be compromised and a hacker would gain access to the credentials.
I think it depends on how accessible / secure your source code or compiled code is. Developers usually have copies of the code on their dev boxes, which are usually not nearly as secure as production servers, and so are much more easily hacked. Generally, a test user / pw is configured on the dev box, and in production, the "real" pw is stored in much more secure config files. Yes, if someone hacked into the server they could easily get the credentials, but that is much more difficult than getting into a dev box in most cases. But like I said it depends. If there is only one dev, and they have a super secure machine they work with, and the repo for their code is also super secure, then there is no effective difference.
What I do is to ask the credentials to end user initially and then encrypt and store them in a file. This way, I don't know their connection details and passwords as a dev. The key is a hashed binary and I store it by poking ekstra bytes in between. One who wants to crack it should find out the algorithm used, key and vector lengths, their location and the start-end positions of the byte sequence keeping the values. A genius, who would also reverse engineer my code to get all this information would break into it (but it might be easier to directly crack the end user's credentials).

Password protection and other security measures for MS Access database

I have been asked to secure an Access database at the highest level possible, and something tells me password protecting the file is not sufficient. We have really sensitive data and I need to protect it to the greatest extent possible. Any ideas?
This has been an issue that I have had for several years with Access 2003. We set a Database Password on the database to lock it down so users would need the password to access it. Not necessarily the best option and kind of a pain.
Since you are using MS Access 2007 you might want to check out want Microsoft says are database protection options.
First, when discussing security, we have to define the threat model.
Common threats are:
Unauthorized access of data: Someone that shouldn't be able to read data, is able to read data.
Unauthorized modification of data: Someone that shouldn't be able to modify data, is able to modify data
Unauthorized destruction/corruption of data: Someone is able to vandalize the database
Privilege escalation: Someone who should be able to read or write some of the data, is able to read or write more than intended
Data exfiltration: someone who should be able to read some data is able to copy large amounts of data and move it to an external (or less protected) system.
Malware insertion: someone is able to insert malicious code into the application
The main defense for Access, as discussed, is encrypting the database using a database password. When using an accdb file, this generally offers sufficient protection against unauthorized access and modification of the data. This is a "one privilege fits all" approach, there is one password, if you have it, you have all privileges and can read, write, and insert components at will. Also, when you have write access to the file, but not the password, you are able to damage or delete the file.
A level higher is securing the Access file: using a secure file server to only serve the file to those who should have access to it. This comes with practically all benefits of encryption, and protects against destruction too, as unauthorized users cannot access the file. This also allows us to revoke rights to that folder, assuming the user hasn't made a copy.
If we want to work with user rights, we can separate the file into a front-end file, which does not contain privileged data, and multiple backend files, and secure these files separately, by either using a different password for each file, or storing them on separately secured locations. Again, secure locations offer the additional benefit of protecting against destruction.
Since Access requires users to have write permission to the file (for placing locks) to have read access, however, we can't easily separate read and write permissions this way. One approach I've seen used is using a "shadow folder", where a virtual folder is created for read users, and upon accessing the folder, the most recent database file is placed in it, and overwritten each time. Setting this up, however, is nontrivial.
Another approach which is very common is trying to use VBA to limit which actions users can take, and allowing them only to open specific forms and take specific actions on them. This is possibly combined with tricks like disabling the bypass key, and/or creating a compiled copy (accde/mde) without the original code. However, these will only stop novice attackers, and can practically always be bypassed, either by using a non-Access program to read the data (which will ignore any restriction imposed by VBA), allowing the bypass key through COM, disabling VBA altogether on the machine, etc. A compiled database only makes it impossible to view and modify the code, not the data, and this also can be bypassed by experts by manually reconstructing the code (example commercial service that offers this). Thus, while this may look like proper security at first glance, it has severe flaws.
Compiling the code is useful when combined with signing the code, to protect against unauthorized malware insertion. Since a decompiled, modified and then recompiled copy won't have a valid signature, assuming the attacker can't access the trusted certificate used to sign the code, and systems can be configured not to open compiled databases without that signature, this can help detect malicious modification of the database.
If we want to have separate user privileges, but cannot enforce this using separately secured folders, an option is to have separately encrypted backends with different keys. For usability purposes, we can use a key encryption key to have a separate password for each user, and have that password grant access to the backends which the user is allowed to use. I've created a sample of a database that uses key encyption keys for this Q&A, but nowadays I'd make some changes, such as using a single front-end with both the KEKs and linked tables to the encrypted databases, and using the CNG API for fast encryption in VBA.
Note that some of these options add a lot of complexity, and none properly protects against data exfiltration (which is an increasing threat in the country + sector I work in). Often, it's a lot more simple, in terms of infrastructure, management, etc. to use a different back-end than Access. This can still allow you to use Access as the front end, so users might not even notice a change, but management of permissions is determined by the back end, which can either be secured by using different passwords for each users, or, in case of SQL server, by linking security to an AD domain (SSPI).
In SQL server, we can also add logging, restrict fetching large datasets by only granting rights to stored procedures and limit the amount of requests over time, to mitigate data exfiltration. However, the added complexity this brings to using Access as a client often makes choosing a different client more sensible, if you only use stored procedures linked tables are not available and Access tends to make more requests than necessary.
Note that when choosing to use a different back-end, it is still recommended to compile and sign the Access database to mitigate malware insertion, which is not dependent on the back-end used.
Bonuses:
What about user-level security? That was a technology specifically intended to offer per-user read and write rights, and separate rights for modifying the database and managing users. Unfortunately, it was insecure and there are many tools out there to remove it, and it only applies to the mdb and mde database formats, so is not of any use.
And, of course, you can also secure the user by securing the environment that Access runs in. I've seen a deployment where users are only allowed to access resources in a virtual environment that is behind a firewall disallowing all internet access, is limited to only opening this specific database, doesn't allow storage devices, and doesn't share the clipboard with the main environment. That allows you to have a secure database by using VBA, but severely limits usability of the database (especially the copy-paste limitation frustrates users, but copying and pasting could be used for data exfiltration).
I would suggest you put it on a file server and have a strict access control list.
In the database force users to log in then
add triggers to write out audit info when a record changes (with the user info,date/time).

Securing SQL queries, insuring that no one person knows that password

What are some effective and secure methods of securing SQL queries?
In short I would like to insure that programmers do not see the passwords used by the application to perform queries. Something like RSA or PGP comes to mind, but don't know how one can implement a changing password without being encoded in the application somewhere.
Our environment is a typical Linux/MySQL.
This might be more of a process issue and less of a coding issue.
You need to strictly separate the implementation process and the roll-out process during software development. The configuration files containing the passwords must be filled with the real passwords during roll-out, not before. The programmers can work with the password for the developing environment and the roll-out team changes those passwords once the application is complete. That way the real passwords are never disclosed to the people coding the application.
If you cannot ensure that programmers do not get access to the live system, you need to encrypt the configuration files. The best way to do this depends on the programming language. I am currently working on a Java application that encrypts the .properties files with the appropriate functions from the ESAPI project and I can recommend that. If you are using other languages, you have to find equivalent mechanisms.
Any time you want to change passwords, an administrator generates a new file and encrypts it, before copying the file to the server.
In case you want maximum security and do not want to store the key to decrypt the configuration on your system, an administrator can supply it whenever the system reboots. But this might take things too far, depending on your needs.
If programmers don't have access to the configuration files that contain the login credentials and can't get to them through the debug or JMX interfaces then that should work. Of course that introduces other problems but that would potentially satisfy your requirement. (I am not a Qualified Security Assessor - so check with yours to be sure for PCI compliance.)

What is the (most?) secure way to handle database connections in a web application?

I have a web application written in Perl using PostgreSQL.
When accessing the PostgreSQL database I need to supply both username and password. In order to have the password available for unattended start-ups of the system I need have that password embedded in my application or in a configuration file or as an environment variable configured in Apache.
In either case I have to have the password in clear text format somewhere.
How is it done in real web sites?
The most secure way to do it is to have a configuration file, and put that outside the public folders.
Make sure the password is somewhere the web server is never going to serve. If possible put it outside the webroot; if that's not possible,
Make sure the file containing the password is readable only by the user the web server runs as, and not writeable by anyone
Rotate it regularly, to minimise the impact if it does somehow leak
Make sure that the database user you're using has minimal permissions. Eg, for a Wordpress installation, create an account just for Wordpress to use, and give it access only to the databases it actually needs
Configure the database to only accept connections from the web server, to minimize the impact of a leak by preventing the attacker from being able to use that password from just any old random node on the net
You can "trust" your Web server's IP (or the localhost, if it's the same node) in your PostgreSQL's pg_hba.conf, and use no password at all. At least, I don't think it's less secure than storing the database password somewhere in the file system of your Web server.
Of course, you can try encrypting and obfuscating the password somehow. But this security through obscurity is not really a barrier for someone who has managed to get into your Web server, especially when all the Perl source code is there to read.
You can store the password in ~/.pgpass (for the web server user, of course). This is obviously not safe in shared hosting where the same user is used for many different websites, but if you have a dedicated setup it often works very well. See http://www.postgresql.org/docs/current/static/libpq-pgpass.html.
The important thing is to store it outside the general web tree.
Use Firewall IP:port filter at PostgreSQL Server and limit the access to only IPs of your web-server.

Is It Secure To Store Passwords In Web Application Source Code?

So I have a web application that integrates with several other APIs and services which require authentication. My question is, is it safe to store my authentication credentials in plain text in my source code?
What can I do to store these credentials securely?
I think this is a common problem, so I'd like to see a solution which secures credentials in the answers.
In response to comment: I frequently use PHP, Java, and RoR
I'd like to see some more votes for an answer on this question.
Here's what we do with our passwords.
$db['hostname'] = 'somehost.com'
$db['port'] = 1234;
$config = array();
include '/etc/webapp/db/config.php';
$db['username'] = $config['db']['username'];
$db['password'] = $config['db']['password'];
No one but webserver user has access to /etc/webapp/db/config.php, this way you are protecting the username and password from developers.
The only reason to NOT store the PW in the code is simply because of the configuration issue (i.e. need to change the password and don't want to rebuild/compile the application).
But is the source a "safe" place for "security sensitive" content (like passwords, keys, algorithms). Of course it is.
Obviously security sensitive information needs to be properly secured, but that's a basic truth regardless of the file used. Whether it's a config file, a registry setting, or a .java file or .class file.
From an architecture point of view, it's a bad idea for the reason mentioned above, just like you shouldn't "hard code" any "external" dependencies in your code if you can avoid it.
But sensitive data is sensitive data. Embedding a PW in to a source code file makes that file more sensitive than other source code files, and if that's your practice, I'd consider all source code as sensitive as the password.
It is not to be recommended.
An encrypted web.config would be a more suitable place (but note can't be used with a web farm)
It appears the answer is the following:
Don't put credentials in source code but...
Put credentials in a configuration file
Sanitize log files
Set proper permissions/ownership on configs
Probably more depending on platform...
No, it is not.
Plus, you might want to change your password one day, and probably having yo change the source code may not be the best option.
No. Sometimes it is unavoidable. Better approach is to have an architecture set up where the service will implicitly trust your running code based on another trust. (Such as trusting the machine the code is running on, or trusting the application server that is running the software)
If neither of these are available, it would be perfectly acceptable to write your own trust mechanism, though I would keep it completely separate from the application code. Also, would recommend researching ways to keep passwords out of the hands of predators, even when stored on local machine - remembering that you can't protect anything if someone has control of the physical machine it is on.
If you control the Web server, and maintain it for security updates, then in the source (preferably in a configuration module) or in a configuration file that the source uses is probably best.
If you do not control the Web server (say, you are on a shared or even dedicated server provided by a hosting company), then encryption won't help you very much; if the application can decrypt the credentials on a given host, than the host can be used to decrypt the credentials without your intervention (think root or Administrator looking at the source code, and adapting the decryption routine so that it can be used to read the configuration). This is even more of a possibility if you are using unobfuscated managed code (e.g., JVM or .NET) or a Web scripting language that resides in plaintext on the server (like PHP).
As is usually the case, there is a tradeoff between security and accessibility. I'd think about what threats are the ones you are trying to guard against and come up with a means to protect against the situations that you need. If you're working with data that needs to be secure, you should probably be redacting the database fairly regularly and moving data offline to a firewalled and well-protected database server as soon as it becomes stale on the site. This would include data like social security numbers, billing information, etc., which can be referenced. This would also mean that you'd ideally want to control the servers on your own network which provide billing services or secure data storage.
I prefer to keep them in a separate config file, located somewhere outside the web server's document root.
While this doesn't protect against an attacker subverting my code in such a way that it can be coerced into telling them the password, it does still have an advantage over putting the passwords directly into the code (or any other web-accessible file) in that it eliminates concern over a web server misconfiguration (or bug/exploit) allowing an attacker to download the password-containing file directly.
One approach is to encrypt The passwords before placing the password in config.web
I'm writing this for web service app that receives password, not client:
If you save hashed passsword in source code someone who views the source code won't be able to help himself with that hash.
Your program would receive plain password and hash it and compare both hashes.
That's why we save hashed passwords into databases, not plain text. Because they can't be reversed if someone for example steals db or views it for malicious purposes he won't get all users passwords, only the hashes which are pretty useless to him.
Hashing is 1 way process: it produces same value from same source but you can't compute source value out of hash.
Storing on client: when user enters pass u save it to db/file in plaintext, maybe obfuscate a little but not much u can do to prevent someone who gets a hold of that computer to get that password.
Nobody seems to have mentioned hashing yet - with a strong hash algorithm (ie SHA-2 and not MD5), it should be much safer.

Resources