Quick question:
Is it worth the extra time and effort to encrypt Dbase data and guard against SQL injection when you are working on code that will serve only on a local intranet and where only two employees (non coders) are authorized to make use of it?
Short answer - yes, it is.
Attackers look for weak links, and you don't want your application to be a weak link. For instance, if you do not encrypt user credentials in your database and don't guard against SQL injection, an attacker who can get onto your internal network can easily steal the credentials of your users; if they have re-used passwords, this means the attacker can now use those credentials stolen from your "weak" system to gain access to a much "stronger" system.
Also - this is the way we're building web applications now; any framework you use will make the additional effort almost minimal - arguably, not doing these things is more effort than doing them if you use tools like Ruby on Rails, the Zend framework etc.
Its not about one or two user but basic sanity. You don't need to encrypt complete data but only sensitive data like user credentials. Secondly for sql injection its very minimal line of code that you have to use, instead of normal statements use preparedstatements for query. I don't see any hurdle here.
If you store data in normal format, anyone having access to DB can retrieve operator credentials and anyone having access can jeprodise the user data by using sql injections.
Related
Recently I had to make an application that later on had to be uploaded to multiple web-servers. Doing this I realized that when storing the admin pass and username's into a json file does not need a db connection so it works all the time. Also when saving the configuration inside json I can just copy my application to web-server and then just go to the browser to do the configuration.
When using a database for this I have to configure this hard coded. Than the db connection would be declared inside a connect.php or config.php. When uploading the application I can't use it because there is no db connection. And I cant set A db connection from within the application itself because I can't login even if I could it would be like a car-key inside a closed car.
My dilemma: Is this the right way, is this save, is this efficient and above all how did you guys do this.
What is the best way to store admin login and configuiration data
The usual solution is to move the password out of source-code into a configuration file. Then leave administration and securing that configuration file up to your system administrators. That way developers do not need to know anything about the production passwords, and there is no record of the password in your source-control.
In other words, it is perfectly normal to have a config.php containing a define("DB_PASS", "topSecret");
Provided access to the config.php file is correctly administered, this method is secure.
Lynks is correct that this is common and is better than having the password in your source control, however if this is a production system that you are designing, I strongly recommend using a different mechanism for user authentication.
Most databases will allow you to use local system users and groups, or external LDAPs to manage your user credentials. Most application servers will have mechanisms for this as well, this is not a new problem. Some systems will allow you to create secure keys (like SSH keys) for trusted users to allow password-less login.
Having passwords in clear anywhere on a production systems is a BAD IDEA, at least use a lossy hashing method to scramble it. Remember as soon as you are dealing with passwords it is YOUR responsibility as a designer and developer to make your best effort to keep it safe. Please evaluate all your options before deciding on the easy solution that could cost you and your customer serious embarrassment later. What technologies are you using? Maybe we can help you find the options available to you.
Remember, nothing lives in total isolation. For example even if this is not a critical system, a lot of places will use a certain pattern for passwords which will give potential hackers a clue for hacking other accounts. If you manage passwords for multiple users, some users use the same password for a lot of things.
This post is not meant as a lecture but a plea for you to make sure you explore all avenues available to you to keep you reputation and your customer safe. Think of it as a challenge, or puzzle and have fun tackling it.
as you guys know that the Hardcoded coding in exe file can easily be seen through some Softwares (e.g. code reflector), I want to know whether how can I Hide my connection string having information of sql server username and password to connect to database in windows forms application from being seen through any code reflector so that any one else Except me may never be able to use my application without my permission.
As commented, you are better off using Integrated Security, however if you are targeting a SQL Server with say Mixed Mode Authentication you could use the Data Protection API to encrypt the connection string in the app.config. Here is a great article on the topic:
Protecting application secrets, such as database connection strings
and passwords, requires careful consideration of a number of pertinent
factors such as how sensitive the data is, who could gain access to
it, how to balance security, performance, and maintainability, and so
forth. This article explains the fundamentals of data protection and
compares a variety of techniques that can be used to protect
application settings. The author discusses what to avoid, such as
hiding keys in source code and the use of Local Security Authority. In
addition, he presents some effective solutions such as the Data
Protection API.
Safeguard Database Connection Strings and Other Sensitive Settings in Your Code
How To: Use DPAPI to Encrypt and Decrypt Data (C#/VB.NET)
I have 4 new data entry users who are using a particular GUI to create/update/delete entries in our main database. The "GUI" client allows them to see database records on a map and make modifications there, which is fine and preferred way of doing it.
But lately lot of guys have been accessing local database directly using PGAdmin and running bulk queries (i.e. update, insert, delete,etc) which introduces lot of problems like people updating lot of records without knowing or making mistakes while setting values. It also effects our logging procedures as we are calculating averages and time stamps for reporting purposes which are quite crucial to us.
So is there a way to prevent users from using PGAdmin (please remember lot of these guys are working from home and we do not have access to their machines) and running SQL queries directly in the database.
We still have to give them access to certain tables and allow them to execute sql as long as it's coming through a certain client but deny access to same user when he/she tries to execute a query directly in the db.
The only sane way to control access to your database is converting your db access methods to 3-tier structure. You should build a middleware (maybe some rest API or something alike) and use this API from your app. Database should be hidden behind this middleware, so no direct access is possible. From DB point of view, there are no ways to tell if one database connection is from your app, or from some other tool (pgadmin, simple psql or some custom build client). Your database should be accessible only from trusted hosts and clients should not have access to those hosts.
This is only possible if you use a trick (which might get exploited, too, but maybe your users are not smart enought).
In your client app set some harmless parameter like geqo_pool_size=1001 (if it is 1000 normally).
Now write a trigger that checks if this parameter is set and outputs "No access through PGAdmin" if this parameter is not set like from your app (and the username is not your admin username).
Alternatives: Create a temporary table and check for its existance.
I believe you should block direct access to the database, and set an application to which your clients (humans and software ones) will be able to connect.
Let this application filter and pass only allowed commands.
A great care should be taken in the filtering - I would carefully think whether raw SQL would be allowed at all. Personally, I would design some simplified API, which would make me sure that a hypothetical client-attacker (In God we trust, all others we monitor) would not find a way to sneak with some dangerous modification.
I suppose that from security standpoint your current approach is very unsafe.
You should study advanced pg_hba.conf settings.
this file is the key point for use authorization. Basic settings imply only simple authentification methods like passwords and lists of IP, but you can have some more advanced solution.
GSSAPI
kerberos
SSPI
Radius server
any pam method
So your official client can use a more advanced method, like somthing with a third tier API, some really complex authentification mechanism. Then without using the application it will at least becomes difficult to redo these tasks. If the kerberos key is encrypted in your client, for example.
What you want to do is to REVOKE your users write access, then create a new role with write access, then as this role you CREATE FUNCTION defined as SECURITY DEFINER, which updates the table in a way you allow with integrity checks, then GRANT EXECUTE access to this function for your users.
There is an answer on this topic on ServerFault which references the following blog entry with detailed description.
I believe that using middleware as other answers suggest is an unnecessary overkill in your situation. The above solution does not require for the users to change the way they access the database, just restricts their right to modify the data only through the predefined server side methods.
I have a database that many different client applications (a smattering of web services, some java apps and a few dot net applications) connect to. Not all of these are running on windows (Sadly, otherwise it would make this an easy answer question with just enabling windows authentication for database connections). At the moment, the passwords are stored in various configuration / properties files lying around the systems. Ideally, only the support staff have access to the servers where the files are running, but if someone else gains access to one of the servers, they would have enough database permissions to get a fair whack of data as it stands now.
My question then, What is the best way to keep the passwords configurable, without having it too easily available to the casual human reader?
Edit Just to clarify, DB server is Windows Server 2003, running MSSQL 2005.
PS: I don't see any questions that this duplicates, but if there are, please feel free to close this one.
I'm assuming you want to hide the passwords from casual observers. If they were evil, steely eyed observers with access to all the source code on one of the machines that connects, then they can get the password with a bit of reverse engineering.
Remember that you do not need to use the same protection for each different client. A few steps:-
Create different database accounts for different systems that access your database
Limit access on the database to only what they need using your inbuilt database GRANTs
Store a triple DES (or whatever) key inside a password manager class on your database. Use this to decrypt an encrypted value in your properties file.
We have also considered having the application prompt for a pass-phrase on startup but have not implemented this as it seems like a pain and your operations staff then need to know the password. It's probably less secure.
Let's assume the following common scenario:
You use the same code base for all environments and your code base has the database passwords for each environment.
The personnel (sysadmins, configuration managers) that have access to your production application server are allowed to know the production database passwords and no one else.
You don't want anyone with access to the source code to know what the production passwords are.
In a scenario like this, you can encrypt and store the production passwords in property files that your application. Within the application you can include a class that reads the passwords from the property file and decrypts it before passing it to the database driver. However, the key and the algorithm used to decrypt the password are not part of the source code but rather passed to the application as a system property at runtime. This decouples the knowledge of the key from the application source code and anyone with access to just the application source code will no longer be able to decrypt the password because they do not have access to the application's runtime environment (app server).
If you are using Java take a look at this for a more concrete example. The example uses Spring and Jasypt. I am confident that some thing like this can be extrapolated to other environments like .Net
At my old workplace we used to have a system whereby all passwords were encrypted (using Triple DES or whatever we were using at the time). The passwords were often stored in properties files (this was in a Java system).
When the password needed to be changed, we could simply use "!plaintext" as the value, and then our code would load it up, encrypt it, and store the encrypted value back in the properties file.
This meant that it was possible to change the password without knowing what the original value was - not sure if that's the kind of thing you were asking for!
It sounds like there is no easy answer (because of the different types of applications that connect)... really, the only issue I see is the Java Apps which seem to connect directly to your database. Is that correct?
If so, here's what you can do:
1) Change any client-side applications that connect directly to the DB to go through a service. (If they have to connect directly, then at least give them a first step to "get password" from a service, then they can connect directly).
2) Store the passwords in the web.config file (if you chose to do .Net web services), and then encrypt the "connection strings" section of the file.
Don't use passwords, server to server authentication can usually be performed by using a key file or a client cert or some other way other than a password.
You could use a reversible encryption algorithm e.g. Blowfish to store the passwords as a stopgap measure. There should be a number of free libraries you can use to build this into all your programs that need this access.
Bruce Schneier's page on Blowfish
Wikipedia article on Blowfish
For the java stuff, if you're using an app server see if you can define a data source, and your apps can get at the data source using JNDI. That way, managing the datasource (including connection details) is handled by the app server, and your application code has to do is ask for a datasource.
NTLM Authentication or LDAP-based (Active Directory) authentication should be available to you with a bit of effort. This would allow you to use your "windows authentication" across applications.
It may mean a bit of a migration for your operations staff, but SSO for a set of applications is nice.
Yes I have to agree with the option of storing the (salted) hashes. I would recommend a (salted) SHA256 hash of the password stored in the database. Also don't forget to enforce secure password rules.
My interpretation of your question is that you are asking specifically how to store configuration passwords that your code will use to connect to services it depends on such as a database or third party API. In that case, you may want to consider using a service which provides a secrets container such as Hashicorp's Vault.
You can think of vault as a web service your application can connect to in order to lookup the secrets your application needs at application runtime.
As an example, lets assume your application needs to connect to a database but you don't want to store your database credentials with your application source code in your version control system. Furthermore, lets assume that you want the database credentials used by your application to be different each time your application starts. In this case, you could enable and configure the database secret back end in vault. This means that vault will dynamically create your database credentials as a service, and then provide your application with a revocable leased token for some duration of time. Vault, of course, will allow you to store any secret in it.
Vault provides secure ways for your application to connect to it. One such authentication method uses what is known in vault as the Cubbyhole Secrets Engine.
Using encryption is not a good idea. If someone compromize the key he can decrypt it. Use a hash algorith with salt to store paswords. Hash algorithms are one way so its not reversible. But they are vulnerable to dictionary attacks so use salt (concatane plain text with something long and verbose than hash it). It also protect database from internal attacks.
What is the best way to centralize and secure the connections strings used by applications? In my environment we have many internal applications. Each application requires one or more connection strings in order to access the database. We have a goal of centralizing all these connection strings (particularly SQL logins and passwords) so we could change passwords in one place instead of in 35 different .config files, registry entries etc.
Currently we are using a home grown component which pulls the connection string information from an access database, this covers the centralization requirement but isn't particularly secure. In addition we have applications written in languages from classic asp, vb6, delphi, c++, .net so the solution would need to be usable by all those applications.
Does anyone have an idea of how to do this better, or do we need to rework our whole approach to the way our applications access the database.
The company I work for has used a similar situation through a SQL Server database instead. We ended up creating a COM-compliant .net dll to simplify and secure the API into the database and to ensure that the same logic is used between classic asp, .Net, and DTS packages. It has worked out great for us for year and while there are some refactoring items a lot of us would like to do with it, it's been great to address issues like server migrations or renamings.
I think you are on the right path; however, I would recommend the following changes:
Try to move to a true database server. Access is great for MS Office but not for something of this scale.
Build an administrative console that allows for auditing of who is adding and editing information (secure who has access to what settings too).
Build a COM-compliant DLL so that it can be consumed by other systems in a secure and consistent manner.
EDIT:
Something that I have noticed after working years in a system like this is that it ties your hands slightly on some solutions. Many tools out there (i.e. nHibernate, Elmah, etc. in the .Net world) really are limited when the connection string is no longer in the config files. Many can be easily modified to use your API; however, it is something that takes more time to investigate if you want to use it. Just a FYI on that.
You can use Windows server to create users that are allowed to access your SQL Server database. Then you can use integrated windows login in connection strings.
BTW Storing passwords in public MDB renders them irelevant. Same as they don't exist.
Is it not possible to move to Window Integrated Security in the connection strings, then you do not have to worry about the security aspect as much (unless you need to secure the actual location of the connection I guess).