C# SQL connection string best practice - sql-server

I have a winforms application that connects to a database with a connection string and a generic user
"Database=DBADAS;Server=TMT123\\SQLEXPRESS;User ID=user; Password=*****;
After connecting into the database with a login dialog, we check if the user and password are existent in the user table from the database.
My question is now if this is a good practice? because basically in the connection string there is every information needed to crack the server.

There are a few ways to go about this safely. Since it's a Winforms app and not a web application, most of your security risks involve someone already in your network peeking at the connection string. This adds a layer of security in and of itself.
1. Hardcoded
You can hardcode the connection string that fetches the users into a DLL and make your application depend on that DLL. I only suggest this because it sounds like the "generic user" password is permanent; otherwise, you'd have to recompile code every time you changed the password, then deploy again. This is very secure, however, as the value isn't stored in plain text.
2. App.Config
You can stick it in a configuration file. Within a secured network, this is probably the most versatile option, as you can store multiple strings and easily update them without updating the full application. This goes well alongside settings like a "DebugMode" setting, etc. Using App.Config or another XML file is ideal, but you can roll a quick and dirty .txt file, too.
3. Database
Probably the most secure way of all, as you can encrypt your database and code your programs to fetch their connection strings and login information from that database by using an unrelated login. This allows greater control over what can be reached by the application when a user has not yet logged in. It also prevents the software from operating outside of the network, which may be desirable.
4. Internal API
Having a separate application serve this data divorces user capability from your concerns, as the API and your app can exchange verification keys to see if your app even has permission to try to connect. This is my personal favorite, but obviously the most work to set up.
5. Registry Entry
Depending on how you have this installed, it may work well to embed the tokens you need in the Registry. This guarantees the app requires admin permissions to install, and allows you to use Windows security to restrict access to the hive.
Again, since it's an internal non-web app, I wouldn't worry too much about the plain text of the connectionstring; if someone has gotten this far into your network, chances are you have much bigger problems already. I wouldn't leave it floating as a plain text file in a local directory, but any degree of security above that is probably acceptable for your purposes.

Encrypting Web.Config
Open Command Prompt with Administrator privileges
At the CommandPrompt, enter:
cd C:\Windows\Microsoft.NET\Framework\v4.0.30319
In case your web Config is located in "D:\Articles\EncryptWebConfig" directory path, then enter the following to encrypt the ConnectionString:
ASPNET_REGIIS -pef "connectionStrings" "D:\Articles\EncryptWebConfig"
Use Aspnet_regiis.exe tool with the –pef option and specify the application path as shown above.
Note: The parameter "connectionStrings" is case sensitive.
For Winforms: You need to rename your app.config to web.config encrypt it by using steps 1 to 3 and again rename it to app.config.
Reference: https://www.codeproject.com/Tips/795135/Encrypt-ConnectionString-in-Web-Config

Related

WCF ServiceHost restricted user netsh/httpcfg

I use a self hosted service within a WPF application for certain tasks. The service host is started at runtime and its base address is http://localhost:Whatever-port-is-free-at-runtime. This works fine when the user has admin rights but problems arise when the application is ran by a restricted user.
I found some suggestions on the web that suggested reserving the url using netsh/httpcfg which works fine for admin users but fails for restricted users because they presumably do not have the rights to use these tools to reserve a url. As the port number is not known until runtime the url reservation command can logically only be run at runtime which means the process will be initiated by a restricted user without the right privilege to execute the command. Am i correct in thinking this?
What i would like to know is if there is a suitable work around? Also, i would like to know if a restricted user can open a locally hosted WCF service at all, since solving the aforementioned problem will be pointless if the restricted user couldn't do this.
This question perfectly describes my first issue of URL reservation
In WCF, the HTTP and HTTPS bindings use HTTP.sys under the cover to reserve a required URL for a specific WCF service, which is the same path IIS itself follows while doing the bindings for the websites it manages. This explains why the process performing the HTTP/HTTPS binding is required to run in elevated mode.
That being said, I would solve your issue in two different ways:
Option 1: use a different kind of binding. NetTcpBinding and NetNamedPipesBinding, for example, do not generally require administrative privileges: this is by far the easiest way to go.
Option 2: setup the required namespace reservation at installation time. This way you may ask your users to perform the installation in elevated mode and later allow restricted accounts to run it. While performing the initial installation/reservation you may also find out an available port to use (and perhaps save it in a configuration file for later reuse).

Machine config instead of app.config files for console apps

Is it possible to use connection strings in a Console app's app.config file in a single machine config file instead? So all console apps on the server can use the same file?
You could, but that would mean that any .NET application could gain access to your database.
I would advise against it, for several reaons:
A possible security hole.
Most developers would look for this information in app.config not machine.config.
You may end up sharing connection strings that only one or two applications need with all applications.
You can't limit what applications will be able to use the connection strings.
You will not be able to simply move the application to another machine, with the app.config file and have everything just work (you will also need to import the connection string information to the new machine.config).
You really should keep the configuration with the application that uses it.

Ability to detect if this is the users first login to Windows 7

I have an windows application (WPF) in which we are running on each login, however when the user first logs into a new PC the application will need to do some specific tasks, but only on the users first login and never on subsequent times.
Is there a way in .Net 3.5 to query wether the user has logged in before (ie some kind of login count)?
Failing any native support I will create a txt file in the users registry however I wanted to know if there is a native way of achieving this first.
We use redirected folders so the user may have already logged into a PC on our network these special events should only occur when the user hasnt logged in onto the PC and Windows has had to create a new profile for the user on the PC.
If I am not clearly explaining what I am seeking, please dont hesiate in letting me know.
Matt
Failing any native support I will create a txt file in the users registry however I wanted to know if there is a native way of achieving this first.
I'd recommend going with this option. Don't try to detect it, just create your own state on first run.
I suggest this, not because it is technically impossible to achieve the functionality you describe, but because it is a better user experience. It provides an easy way to re-do the action without having to recreate the user.
... a txt file in the users registry ...
I'm not sure what this means. You can create text files under the user's profile directory, and you can insert string values in the registry (but not files of any sort).
As for the particular mechanism, I suggest you consider:
An App.Config value. Clearing out the value is easier to support or batch-script than a registry value, and makes the user less scared that their machine will explode if you have to tell them to edit the settings. Users are scared of the registry.
A sentinel text file under the user profile directory. Wiping out the file is super-easy to support and batch-script. Instead of editing a text file, they can just delete one. But this makes it so you have multiple config mechanisms, so multiple points of failure. I'd only do this if I were using the App.Config for additional settings in the program and thought the user wouldn't be technical enough to hand edit it.
The windows registry. Remote registry access might be easier than remote file access, if you're having to do remote troubleshooting. It also might be easier to mess with via group policy, in case this is an intranet app and you need to force a re-run on all machines in your org.
I'd carefully consider my options and which is most likely to ease support (be understandable by my users) before committing to one. I'd also consider the remote-troubleshooting/remote reset scenario.
This may not be what you're looking for but I'm hoping it will help you anyway.. I do not know from the top of my head how to do this in WPF but I do know you can use an "unattend.xml" file and the FirstLogonCommands to execute a script or application on first logon. I have used this for Windows 7, it may not apply to XP.

JSP website pre-database configuration

I'm working on a website in JSP (in GWT really, but on the server side, it's really just JSP), and I need to configure my database.
I know HOW to code in the database connection etc, but i'm wondering how/where the database config should be saved.
To clarify my doubt, let me give an example; in PHP, a website usualy has a config.php, where the user configures the database, user, etc (or an install.php generates it).
However, since JSP is bytecode, I can't code this info into my site and have the user modify it, nor can I modify it analogously to an install.php.
How should I handle this? what's the best/most common practice ? I've found NO examples of this. Mainly, where should the config file be stored?
There are several possibilities to do this, what I've seen done include:
Having database credentials in a special file, usually db.properties or some simple XML file that contain the required information (driver, url, username, password, any ORM parameters if needed). The properties file would be placed under WEB-INF or WEB-INF/classes; the downside of this approach is that the user would have to modify the file inside the WAR before deploying it to the application server.
Acquire the database connection via JNDI and expect it to be provided by the application server. This seems to be the most common way of doing this; on the upside, your WAR doesn't have to be changed, however, the downside is that configuring a JNDI data source is different for every application server and may be confusing if your system administrators are not experienced with Java technology.

What is the best deployment approach for WPF applications with local database?

I want to make a WPF application that exists in one directory including all files that it needs: .exe, .mdf database, .xml config files, etc.
the application should work no matter what directory it is in so that it supports this scenario:
person 1 executes the application in c:\temp\wpftool.exe
the application reads and writes to the c:\temp\wpftool.mdf database
person 1 zips up that directory and sends it to person 2 via e-mail
person 2 unzips it to c:\Users\jim\documents\checkout\wpftool.exe, the application reads and writes to the same database in that directory (c:\Users\jim\documents\checkout\wpftool.mdf)
person 2 zips the directory up again and sends it back to person 1 to continue making changes on it
What is the best way to create a WPF application that supports the above scenario?, considering:
there should be no hard-coded database connection strings
what is the best deployment method, click once? or just copy the .exe file out of the /release directory?
reasonable security so that users have to log in based on passwords in the database, and if a third person happens to intercept the e-mail, he could not easily look at the data in the database
Some points on the database side:
Assuming the "New user" already has SQL installed, they'd need to attach the (newly copied) database. Besides having sufficient access rights to attach a database, your application would need to configure the call to include the drive\folder containing the database files. If your .exe can identify it's "new home folder" on the fly, you should be able to work that out.
Define "reasonable security". Any database file I get, I can open, review, and ultimately figure out (depends on how obscure the contents are). Can you obfuscate your data, such as using table "A" instead of "Customer"? Would you really want to? The best possible security involves data encryption, and managing that--and in particular, the encryption keys--can be a pretty advanced subject, depending on just how "secure" you want your data to be.
For the database, I would look into using the "user instance" feature in SQL Express. Combined with the |DataDirectory| substitution string support it makes it very easy for your application to get hooked up.
In all honesty I have not deployed a ClickOnce app leveraging this approach myself yet, but I just thought I would bring it to your attention because it's what I would look into myself if I was building something like you described.

Resources