I have developed an app, which more than 2k users are going to use it. This app is connected to a database which contains some data.
I have some questions:
1. Is it ok to use mysql direct connection in app instead of API for just reading data?
2. Is there a way that someone find my server's information (address, pass, etc) from my application?
App is wpf.
Generally speaking (and as with all generalities there are all kinds of exceptions here, in both directions) it's okay to connect directly to the database if one of these two conditions is met:
The app and the database are on the same computer
or
The app and the database are on different computers, but within the same corporate network and traffic between the app and the database is adequately protected.
and if one of these conditions is also met:
The end user owns the app and doesn't share data with other users (they break it, that's their own problem and no one else's)
or
You issue separate accounts with only the necessary privileges to each user (the user owns the credential)
or
The machines where the application is deployed are controlled by the business, where you can securely deploy the application (and the account credentials it uses to connect to the database) in such a way that end users are not able to retrieve the account credentials directly. (The business owns everything).
It is not generally okay to connect directly to a database over the public Internet, or within a local network where traffic to the database is not adequately protected, and it is not generally okay to let end users have direct access to the database separate from the application (and if a user has ownership of their machine, they will be able to get that access).
I also need to expound on what I mean by "adequately protected". This involves a few things:
A good firewall between the clients and the database. In some smaller environments, the firewall on the OS hosting the database itself may be enough.
Measures to prevent MitM attacks on data packets to and from the DB. For traditional corporate networks, this usually means 802.1x is running even on the wired network, and wifi access is similarly protected (a pre-shared key wifi network like you use at home is not good enough, because anyone who can get the key can decrypt your traffic). Alternatively, you can implement encryption that runs from the client all the way into such a protected network. This is what many corporate VPNs are for (a public VPN service doesn't accomplish this for you). You may also be able to encrypt that actual database connection traffic. I know how to do this for Sql Server, for example, though I'm less clear on what direct support is in MySql in this area.
If you save the information inside your application, it can be found. You should consider using an API to handle the data reading. Applications can be reverse engineerd.
Related
I created an application with a C # programming language and MySQL database.
When I want to install the software on the user's computer,
What software do I need?
MySQL software should be fully installed on the user's system?
Or is there another way?
Is this with a stand-alone database, or are you creating a shared database the client application needs to connect to?
If it's a stand-alone program then don't use MySQL. Use an embeddable database library like SQLite instead. These are far more durable and resilient and can handle abrupt shutdowns and restarts. MySQL needs a lot more care and attention, plus has a huge footprint in terms of memory and CPU consumption. Managing that automatically is not easy. Walking a client through how to repair a damaged MySQL database is not something you want to do.
If it's a shared database then you technically only need the client libraries, but remember, exposing MySQL to the general internet is extremely dangerous and should be avoided whenever possible. If you must, ensure that your users are using SSH or a VPN of some sort for access to restrict who can connect to your database server.
The best plan for a remote application is to build out an API that intermediates between client and database, giving you the ability to layer in access control at every level necessary to protect the data. MySQL has very broad access control, locking down individual records can be hard to do and easy to get wrong. Unless you can trust all users, it's best to not trust any.
You don't need the server installation on the client / remote machine. Just a workbench should be fine through which you can connect to the server and perform any database operations.
I have a problem with new hosting. So far I have been using an fluent nhibernate aproch to access data from remote database. Due to certain circumstances I had to change to another hosting which don't have external database access. End users use internet connections without static IP (it is public for most of them, but it changes every 24-48h) What can I do in my situation to keep changes at minimum in my application ?
Data transfer is in both ways.
My ideas:
Use new hosting ftp to upload files for processing with php. Lots of work.
Design some kind of webaccess service. Same as above.
Out off above questions comes second one:
How access to database is provided in big systems where one can't limit connection only to known and safe sources ?
DMZ ?
If you do not have external access to a database (which is pretty common if not the default) you could use a VPN or SSH tunnel to connect to the external server and access the database as if it were a local one.
I wrote an application in c# & SQLite for storing data of all employees in a company which has around 500 employees. I want to put the database & the application in a file server/shared folder (MS server). Then all employees will have a shortcut of the application in their desktops. I want to make some input fields (text box) enabled/disabled based on the permission of the user runs the application. Whats the best practice for doing that?
I want the user can read/write in the database through my application only (the application is located in the same database folder). I don't want the user to reach the database without my application. How to do that?
I don't want the user to reach the database without my application
If your application will directly access the SQLite database via a Windows file share, this is impossible. Sure, you can make it inconvenient, but it's not really possible.
The only way to achieve this really is by introducing some middleware.
This would typically be a service (WCF perhaps) that listens for connections from your client application, authenticates them, and manages all access to the underlying database. The database would be stored in a location that is visible to the server only, and not visible through a Windows share to your users.
Also, SQLite isn't exactly a great choice for a multi-user system. You can kill two birds with one stone here - switch to a DBMS (MS SQL Server Express is free, also MySQL, PostgreSQL are common free choices) that accepts client connections over a network, and build your application to connect directly to the database server (using integrated Windows authentication may also be possible like this, so you can avoid an explicit logon). In a simple scenario this may be adequate and avoid you needing to build an explicit service layer.
In a more complex scenario, it can still make sense to have a middleware layer between the application and the database - this way, you can change the database design without changing the application design and deploying to all of your client machines - instead, just change the middleware layer in one place and your application won't know the difference.
If you don't want the users to reach your database you should create a client server architecture.
You can run your service on the same machine as the file server (running as a Windows Service) and use WCF for communication between your server and your client. You access your database from your server and let your server authenticate your users and validate that they have access to the application.
You can cheat and try to "hide" database credentials inside your client application, but that is security by obscurity and any one with some programming skills or similar can find out the credentials to the database and connect directly to the database.
I have a WPF C# multi-user applicaton which interacts with Sql Server Express database. Currently I have faced up with the following issue:
How to organize the application and the database in order for several users on different stations be able to work on it , maybe i should put the database file on a server, and make my application on all other stations refer to that server when they interact with the datatbase? If so, how can I provide security of the database file.
Is there any scenario in which I could install my application on server and sign it as server and while installing on other machines point that server?
Any advice on general strategies in such cases would be appreciated.
Thanks in advance!
If all the users are concurrent then your going to need to place the SQL instance on a server that they all have access too..
your also going to need to know look at quite a few things like this such as how your going to manage your transactions and just how your persistence layer is going to function in general.
each of those topics are probably going to breed many more SO questions :)
this could help for some inspiration on how your going to structure the persistance layer..
http://msdn.microsoft.com/en-us/magazine/dd569757.aspx
For multi-user application, you definitely should put the database onto a server. And because the application is for multi-users, the first screen shown when a user opens the application is the login screen (just like the case of web application).
Security isn't a matter, once a database is put in the filesystem, only the users on that computer can access it. And of course, the computer which contains databases is supposed to have only administrators as users. Another point is that Windows may have IIS running, don't put the database files under public root of IIS so that non-user people won't be able to download them through HTTP.
Let's say the users are working on the same office. You can assign any computer in the LAN as a server and install the database on it. Any computer in the same LAN has a LAN IP (eg. 192.168.1.100), your application can connect to this IP for database operations.
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.