If a C# application connects to a mysql server from a client, how do I store the mysql username/password for the connection? If I have it in a config file or embedded in the source it can be found by reverse engineering. It is not possible to give all users a MySql password.
Also, I have a log in for the application. How do I enforce that the user goes through the login process and does not just reverse engineer and comment out the C# code verifying the log in?
Is there anyway manage these connections between MySql and a client side application or must there be a third program on the server side interacting with the database locally to be secure?
Perhaps you can have a two-stage system: Have a SQL account whose only permission is to execute a stored procedure taking the user's username and password and giving them the credentials to use for the real account. When the user logs in, you connect using the restricted account, get the credentials for the real account, and then do your work using that account. You can change the SQL password fairly frequently, too. If you suspect a user of foul play, have the procedure return them a different set of credentials, and track those credentials.
For Winform clients that connect directly to the db this is an age old (10 years or so?) question that may never be solved.
The problem is that no matter how you encrypt or obfuscate the connection string there will always be a point in time at which the string will be represented as plain text in the client computer's memory and therefore hackable.
You have been recommended options by other SOers, i just thought i'd point out what you're trying to work around.
Here is the problem. You are trusting the end user with the binaries which will call MySQL queries. This means, beyond any shadow of a doubt, that a clever user could "take control" and run queries directly.
There are things you can do to improve the situation. It sounds like you are on a LAN. Why can't you give each user their own database user? That means that the authentication is (a) taken care of for you, and (b) you can use "real" MySQL permissions to limit what harm they can do. Also, you could use stored procedures and give them only access to the procs, really limiting what they can do.
You could also consider re-writing as a web-application where you process everything on the server out of their reach.
However, is there really a problem here, or are you just being theoretical?
Related
I've written a C# application and I want to give it to some people to test it out. Therefore, I want to secure my application with a serial key. I don't know if my application is going to be profitable, so I'm not looking for spending 500$ on a ready solution. As .NET C# application is pretty easy to disassembly and even make it a readable code, I don't want a built-in key generator. I want my application to communicate with MySQL, so for example, user enters serial key in welcome window,
and application communicates with database executing a query looking like
"FROM serials SELECT serial WHERE serial = 'user_input'",
then see if there is any result from database.
However, I can't restrict user to do just this query, so if somebody gets login and password from the code, he can know all the serials in my database.
I know that I can run an additional intermediate application on the server, which would just connect to localhost MySQL and return a YES or NO response to the application, and not store the MySQL credentials in user application, however it's also quite expensive, and demands much work.
How can I solve this issue? Is it possible to have just application and MySQL database, to store keys and check for their correctness?
I have the local database in SQL Server 2014 with four tables volume 1.5 GB. The essence of the program to look for in the database records with the user defines criteria. The program is written and it works fine. We should make sure that the program worked and other users who have not installed the server. How to implement this? Was a idea to serialize the data, but as I understand, it is necessary to deserialize all the data and then look for the right record.
As the comments before me already says i think you have 2 options.
Either ship the database with the client (using Sql Express or other similar solutions). That should work fine and will work without a connection to a centralized server but the size of your client package will be quite big. And if you make any changes it will only be locally, but it seems you only make reads to the database from the client?
But if i understand it correctly you install a sql server for each client, since you mention "users who have not installed the server"? Then you already have the problem with a lot of data needing to be sent out to each client, as well as the problem of updating all databases when the data needs to be refreshed.
Another solution is to allow access to the database from the client. This can work in serveral ways, if all your users is in your doman you can handle authentication based on their domain users and skip the authentication part. Then you would only need to send out the client and skip the installation of a big server and all the data.
If they are not on the domain but still on your network you could add a login on your application to allow access to the database or if you trust all your users you could add a read only account and just hardcode the login for that account.
If you want to access the data outside of a trusted environment you should of course add a separate login for each user to allow access and it might even be a good idea to use an api before the database that handles the requests from the client and then does the search to the database in a controlled manner.
I would personally go with using a centralized database to skip all the work of setting up new users and also have a single point to update when the data needs a refresh, but of course it all depends on where your users are.
Normally when we connect to a database, we will select the database driver
type, server name, uid, password and database name. (like ms
sql server ). Is it possible my c# windows form app
auto detect available database connections?
Maybe the ms sql server database is store on the same PC where I
am running the app.
It is like the app can know there is a ms sql server
database and try to connect to the database.
I will aprreciate if you can please provide some example code
Thanks
The SqlDataSourceEnumerator API may be what you are looking for, however I rarely see it used - in part because not everyone wants their servers discoverable, so they turn this feature off. Additionally, even if you can find the servers, it certainly won't tell you the credentials - you need to know those yourself (or use trusted auth).
But in almost all cases (unless you're writing a database utility like SSMS): your user should already know which source they need to connect to (even if that is just a magic opaque string that the admins give them).
For more info, see MSDN which has a full example.
Is there anyway to prevent people from using Reflector.net to decompile my .exe c# application? I know there is a tons of post about this but I don't really care if people can see my code the only thing I want to "hide" is my database connection string.
I am currently using "Settings" in my c# to keep the database connection's info.
I wanted to know if using those string in my project's Settings would prevent people from seeing it ?
I am using DotFuscator in visual studio 2008 but I heard it wasn't preventing people from decompiling my program.
I know I could use a Web Services but my server will be on linux so I guess I can't store web services on Linux.
No. Even if you encrypt the connection string in the program code or in a settings file, you will need to decrypt it, and the program must necessarily contain the decryption key somewhere, which means that someone who is interested enough in finding it will find it, no matter how creative you are in hiding it. Why do you need to hide the connection string? If you are afraid that someone who has your program might call the web services directly and trigger unintended actions, you should look into how the web services are structured, what they allow clients to do, and how the authorization works, and make security improvements there instead.
If your program has the connection string in it, users of your program can get it back out. Even if you encrypt it, they can sniff it when your program connects to the DB server.
If you don't want your users to know your DB login credentials, don't give your DB login credentials to the users. That's the only way.
You could do this by instead giving each user their own credentials, and using the permissions system in the DB server to control what they can or can not do.
As others have stated obfuscation is no real protection for a connection string stored in a client application where the user have access to the binaries.
Don't use a direct database connection from your program unless the user is trusted to use the database directly with the same privileges. Have a service (web service, REST-service, etc) in between that you host on your own server. Linux can host services of any of those types I mentioned (use Mono if you want them in .NET on Linux)
In order to expose your database via a web service using Mono or any other language/framework you can host on Linux you would create a web service method for each atomic operation you want to perform against the database.
An additional advantage over letting the client application access the database directly is that when the client application is using a service between itself and the database you are free to change your data store without affecting the client. You can decide to change the database schema in your database or replace the database with a NOSQL solution or even a flat file.
Having a service instead of communicating directly with the database moves the authentication/authorization requirement one step, so now you need to implement it in the service. Fortunately there is rich support for authentication in a web service.
Take a look at this guide on this specific topic from MSDN. Keep in mind, however that this only shifts the security burned. Now you need to manage the security of the key
Hi i am trying to find the best way (or a good one) to store a ConnectionString (my App will connect to a Database in a Server, it will work with it continuosly) and how to handle with the Admin account. For default all the applications with Login must have an Admin account, right?
I think in that way...
So, you install an App on the Machine, how you will configure the ConnectionString? I think that is wrong asking the user to configure such thing if doesn't understand what it is or it really have to be?
And imagine one day that the ConnectionString have to be changed for any reason, if the Admin acoount credentials to Log in the App are in a Table in the Server, how then it will possible to Log in the App to change the ConnectionString?
This is my problem now... I don't know how this type of things is handled, if are there any rules to handle this, any common way because i am starting to work more seriously with this type of things.
Note: I think that is not important but my App is being developed in WPF.
A really easy way to do DB access security with MS SQL Server is use "Integrated Security = SSPI". With that, MS SQL server authenticates against the Windows user entity under which the database accessing process runs. It all happens seemlessly using MS SQL Windows Authentication without the need to store any usernames or passwords within the application.
Another way to do it is to distribute a config file with the database connection string in it, with at least the password encrypted.
We have many MySQL databases on several servers too, so MS SQL SSPI doesn't cover us.
For server side software I store database connection strings and credentials in a separate XML config file that all the server side software uses. The credentials are arranged topically with all database information encrypted. I use a common file for all the server processes and developed a little encryption / DB config file management GUI so management is simplified and access is universal to all the software using the same code.
For end user software it is too difficult to maintain with local config files because of user maintenance. For "fat client" software I maintain a separate database with encrypted credentials on a server in our DMZ that is universally accessible to anyone havinng that software (there is not that much distributed fat client software.) Our web app software has a consolidated user database that controls access for all users/roles for all apps, and everything is portaled through the one system so it is far easier to mantain the user database.
Frankly, the polyglot system is increasingly ugly to maintain. I would use our main domain LDAP server (Windows ADS), but our company policies keep ALL domain member servers completely firewalled off from access outside our most trusted VPN and thus inaccessible in too many circumstances.
I hope someday to have time to setup a *nix based LDAP server in our DMZ and centralize all credential information there.
With connection strings to a MS SQL server you basically have two options:
Either store a username/password pair in it. Your application has to be able to read it, so theoretically, any user of the application could do the same (he has access to your application, so he can decompile it). Practically, you can encrypt the connection string, with a key stored in your source code or application resources and be quite confident that your users won't be able to read the password.
If you have some users that should be able to use the application and you believe them, and other users that may have access to your application but that shouldn't be able to use it, you can use Windows Authentication, and set Integrated Security=True in your connection string. This assumes you configure your DB, so that the approved users have access to it.
Either way, your connection string should be bundled with the rest of the application. If you ever need to change it, you just release a new version. (This works even for the most primitive version of installation: “copy this bunch of files to a directory on your computer”).
Now, the connection string can be stored pretty much anywhere, the most convenient place probably being application settings file.
If you want to be certain that your users will be able to use only the functionality provided by your application and not access the database directly, you'd have to write something like a web service and connect to the database only indirectly through that.
If you need to store the connection string in a configuration file or somewhere else of your choosing, you might want to encrypt and base 64 encode the encrypted results back into a string. Check here for an Encrypt() and Decrypt() implementation.
It is possible to manipulate files (such as the .config file) during the install of the application. So it is acceptable to ask the user/admin (during setup) for the name of the server (and even for a user name and password provided you encrypt these but I'd rather use integrated security).
For updates of the connection string just make a new installer.
Alternative: store the connection string in active directory or in an other well-known store so all you need to do is change the value in one place.