ship my software with a secure mongodb - c#

so I have a bundled software that a client can download and install (using an msi on win machines).
part of this software is a mongoDB database, that stores client info, configurations, etc..
When the software is first installed, it creates an empty folder for the mongoDB, and whenever the software starts, it starts a mongod process (using C#'s Process.Start()): mongod.exe --dbpath <path> --port <port> --quiet.
My goal is to secure the mongoDB database with a username / password that will be known only to my application.
this will help prevent tampering with my client's data from the outside, as well as make it harder (but not impossible, see below) for the client themselves to tamper with the application's data.
The general idea, I guess, is that on installation (or on startup), to create a user with read / write privileges which my software will use to communicate with the database.
So My questions are:
1. How do I programmatically do this? I guess this is the right direction, but I couldn't find much info on the c# driver docs
2. How do I deal with upgrades? i.e clients who installed a previous version of the software, where the database is not secure at all; i would like to create a user with a password in that case as well.
3. how do I store the application user's credentials in my application? in a config file? but that can be read by the client. any best practices here?
versions info- (unfortunately, because of my company's issues, we're not using the latest product versions); mongoDB 2.6, mongoDB driver for .net 1.5.0.
thanks!
P.S. I have read through the security section on the mongoDB website, but wasn't able to find a simple example for the use case I'm trying to implement.. maybe I'm just missing something simple here..

This is kind of an interesting, unusual use case.
First of all, I want to make sure you're aware of the licensing/copyright implications of bundling MongoDB with your software. You should check out the license section of the mongo project GitHub page and read up on the AGPL.
Second, the easiest part of your question:
how do I store the application user's credentials in my application? in a config file? but that can be read by the client. any best practices here?
This goes beyond MongoDB. If a user owns the system that the mongod process is running on, they could just copy the data files and set up a no-auth mongod on top of your application data. You cannot reasonably stop them from doing things like that, so do not count on your application's data to be secure from the client user. Plus, if you install your application code locally, any decently smart and committed person should be able to extract the username and password from the compiled application code. You can make it hard, but not impossible.
Third,
How do I programmatically do this?
Based on what I just said, I'm taking "this" to mean
on installation (or on startup), to create a user with read / write privileges which my software will use to communicate with the database.
not the part about having it be secure from the person who owns the computer it's installed on, because that's not possible. To do this, I'd either package a mini datafile to start the mongod on top of, one that included users set up already, or include a dump that you use something like mongorestore to load into the mongod after you start it up. The first option is way simpler to implement and should not require you to have to take down and respawn the mongod process, so try that - see if you can set up a mongod with auth how you want it and then transplant user info by copying data files. FWIW, I'm pretty sure the passwords are not stored in plain text in the data files (they are salted), so you won't have that directly exposed from the data files.
Finally,
How do I deal with upgrades?
You'll have to take down their mongod, restart it with auth, use the localhost exception to create the users you need, turn off the localhost exception (optional but why not), and then end that connection and start new ones using auth. It's the same process as in the security tutorials, you just have to do it with C# driver commands. Note that moving between MongoDB versions is also tricky as the seurity model has improved over time, so you should consult the upgrade guide for extra things to do to make sure user schema gets upgraded correctly if you are moving a user from a secure 2.6 to a secure 3.0, say.

C# driver connectionstring can accept login credentials for the database.
mongodb://username:pwd#server:port/dbname
for ex
mongodb://myuser:mypassword#mydbserver:30254/mydb
The best way is to store the data in a config file. If you are worried about exposing it, it can be encrypted and stored. Other less likely option is to store in a resource file and reference that as a string.

Related

Protect Winform Application/Sql Database From Copying

I am using c# (VS2010 FrameWork:v4.0) and SqlServer 2012 to build an application. I searched online to find ways to prevent copying this system and I thought the only part that needs to be protected from copying is the database.
I would like you to provide me with some advises about the issue. And I need answers/opinions about the following :
Do I need to protect also the application (executive file) from copying with the database? If yes, does this mean I have to provide the user with a new copy to install it if the user looses the application files?
One Idea I have in my mind to protect the DB is to save some passwords/keys in DB (in the form of varbinary) and when the device is logged in (runs the app) the application checks for (the MAC address) of the device if it is not saved then the app asks for a key. once the key is used, the device mac address is saved with the key. Is this a right thing to do? is there any advice about it?
If I need to protect the app part from copying, is there any idea how to do it?
I have also read about installing SQLExpress on client PC and That should protect the DB files from manipulation, so I have to provide a way to upgrade/ update DB scripts in the future rather than replacing client's DB with a new one. And I thought to provide a form in the app protected by a password, and I can write a script in a textbox in the form (__For Example: Alter Proc_ ...), and Save it. Can I do this? or would that be a stupid thing to do?
Thanks in advance
You cannot. Any claim to the contrary is snake oil.
The only way to protect your application is to offer it as a service, hosted on hosts you own/control.
To find a way to prevent user from using APP+DB without my permission(for example registering using keys)
It is possible to create licensing schemes where the application runs only on the designated hardware. Your application takes the host fingerprint (eg. net MAC), uploads it to a service you host, you sign the fingerprint with a private key and provide the signature to the application, then the application validates the fingerprint signature using the embedded public key and runs the application. While this sounds doable, there is a number of ways this can and often does go wrong. Users change the fingerprint frequently (eg. hardware update). Fingerprints are difficult to enforce on virtualized environments (VMs can edit their MAC). It is very difficult to harden application code against a moderate hacker willing to attack and bypass your protection, and basically impossible to harden it against a skilled hacker.
But you have also asked about the database and tagged the question sql-server. To that part I can only double down on my previous answer: It is impossible to protect a database against being accessed and/or modified by a on-site administrator, at will. There are secure ways to audit access and modifications to the database, so you can prove tampering and act accordingly (refuse support or charge extra). But you cannot prevent it.
Ultimately what you're asking for is DRM.

Advice for deploying a C# program with database to work over LAN

I've designed a C# game that makes use of an Access .mdb database file to store variables.
The basic idea is that one of the players will 'host' a game, and the other player will join said game, by connecting to the database, reading and writing items into the database. The database is needed to pass variables to and fro the host and client, and both programs check the database regularly for new messages / variables (yes, yes, I couldn't get TCP/IP Remoting to work).
Now, there, the program works fine (mostly the client, since the host modifies only its local database), for as long as the client can find the database file. Currently, the connection string for the client is located in a .ini file, and for the program to work, it (or at least, the server) must be located in the Shared Documents of an XP machine, or the Public Documents of a Vista / 7 machine.
But then some questions occurred to me:
What if the client user places / installs it into another folder in the Shared / Public Documents? I suppose there's a code out there that could 'drill' into the Shared Documents folders to find the path for the database, share names included... is there?
What about installation? The installer default is always "C:\Program Files\GameName". Could it be set (or locked) to a specific folder into the Shared / Public Documents, by default? And is it even recommended to install it into a Shared Folder, what with problems such as Accidental Deletion?
Say, the default is "C:\Program Files\GameName". I could see that a set installation path will solve any connection issues, since every client will look in the same path of the other computer, and it won't matter if it's XP or Vista. Could "C:\Program Files\GameName" be accessible by a C# program over LAN, without any system modification? Are there any security (UAC?) issues?
P.S. Details that people may find in handy:
I'm using Visual Studio 2005. So is my School.
I'm running .NET framework 2.0. So is my school, and unfortunately, I can't change that.
I hate to tell you this, but this is why the approach is fundamentally flawed. What are you going to do when:
File and print sharing on the server is disabled?
The network client is disabled on a client computer?
The server is configured to only allow authenticated users, and the client doesn't have access?
File and print sharing is blocked because of the firewall?
File and print sharing is completely borked for other who-knows-why reasons?
You need administrator access on the server to share a folder, but the current user is not an administrator?
The Access database engine isn't installed correctly on the server or client?
One of the clients corrupts the database? (This is easier than you might think; all it takes is a network glitch where a client temporarily or permanently disconnects from the server).
These are fundamental issues that you can't resolve with the current solution.
Get it working over normal TCP/UDP ports. You'll have a much easier time. There are libraries to facilitate that, see C# Game Network Library - for example it sounds like Microsoft's XNA SDK has functions for networking in a game. If you use a standard method / standard library to implement networking, your odds of success are much higher. Using a client/server architecture means that the server's state won't be corrupted if a client goofs up.
I realize that this probably involves a significant rewrite. Frankly, I don't think you have a choice if you want this game to be commercially successful on a wide customer base without high support costs, and move beyond being a mere experiment.
Get rid of the access database. The described architecture is already 'user unfriendly'
Use either SQL Express or SQL CE which requires no installed database binaries (they can all be included in the applications folder). This way the db will stay in the applications folder (ideally app_Data) and .Net has included support for databases in this folder.
Please stay away from access you will save yourself a lot of trouble.
http://blogs.msdn.com/b/sqlservercompact/archive/2011/01/12/microsoft-sql-server-compact-4-0-is-available-for-download.aspx
I think that there is little point in using Access unless you wanted to use any of the pretty form-based IO that you can you do with its designer. And I doubt that'll be the case here.
I would encourage you to replace all your file IO with a sound data access layer.
Which will rid you of all the "sharing" issues that you are experiencing, file locks, the overcomplicated installation process, etc.
Alternatively to SQL Server Express as suggested above you could also use SQLite http://code.google.com/p/csharp-sqlite/

Secure Database Backend for Windows Application that users can't hack into easily

I'm writing a database driven windows application and both the executable and database need to be installed on the customers machine.
Is there a database that I can use as a backend to my application that the user can't get into even though the user is using the same machine that the database is stored on.
As far as I can tell, Postgres won't work for this, and the versions of access that I have tried are easy to get the crack the passwords for.
My application has to be able be installed on a laptop and be useable even when there is no internet access, so the usual client-server database models just don't work.
I have considered using a VMWare virtual appliance with Postgres installed on some version of linux, but this would have a pretty heavy system load.
I would prefer to not have to use encripted text files or something like that.
Since users (or hackers) own the machine, there is nothing you can do to make it secure. Anything you try will fall into a category called Security Through Obsecurity.
Your best bet is to encrypt your database and try to hide the key in some obscure place in your binary. Since this is an installed application, don't use Database servers. Just use a DB library like Postgres.
How critical is the data? Encrypting data on your system using standard RSA or AES with a key stored and encrypted in your application will keep your mum and dad user away.
But if you can't keep the secret out of the client application, then you're going to have trouble here.
There's a couple of options available to you, depending on your budget.
First, I have used SQL Server Compact Edition 3.5 with a .NET program for doing a local database that was encrypted. The good news was that the file was encrypted and could only be accessed if you had the password. The bad news of course is that your password will probably be in your connect string, unless you do something like a seeded PRNG to generate up the password for you. Also, SSCE requires that it be installed independent of your application -- if for any reason the user uninstalls it through Control Panel, your application won't run.
Second, I have also used a commercial product called VistaDB, and it also supports local database files that are encrypted. There are comparison features of VistaDB versus other database engines available on their website -- but another thing they offer is that they don't have a runtime that has to be preinstalled -- you just add another assembly to your distribution (they claim you can statically link it, but I haven't tried that personally). The local file on disk is also encrypted with VistaDB, and without the password you can't access the underlying database.
Good luck!

how to develop c#.net desktop base software?

i have to develop desktop base software in C#.Net which only produces reports and that reports can be export to any format. that software will be dump into CD/DVD and distributed to all clients and they will install it in their PC (Stand Alon PC). and that will be installer, client can install it himself.
My problem is which database i should choose to build it because this software will be installed by third person. so when one install it database should be install itself, all the data should be in imported into database.
2nd i have to send them month wise data (database exported) which then they will copy/past in specific folder and system itself import it. (that given file (data file) should not be open/read other than my develop software.
is it possible if yes then HOW?
please guide me as i am new comer in VS field but i have programming experience more than 8 years in oracle and 3 months in Java.
This isn't impossible to do.
It sounds like you're wanting users applications to simply interact with a DB that you host. That shouldn't be hard, as there are ADO.net connectors for just about all the popular DBs out there.
I'd suggest simply going with MySQL, ADO.Net connector, and use datasets in your program to read and edit data.
All the client applications would just have to connect to your IP address where you're hosting the central DB and they'd instantly have access to all of that data.
If you're not very experienced in application development, it may be worth it for you or your company to contract a worker to complete this application.
Update
In regards to the update about your client requirements, it sounds like instead you should try connecting to an SQL file that is stored on the client machine. This is EXTREMELY simple to do, and MSVC# has the ADO connector preinstalled. Then, you would have to write another part of the app to perform "updates" every month. You said you need to deliver new data to the customers once a month. Just make the program (when they start it up) check the date, and if required, connect to an FTP site and just download the file to the client machine.
Update II
Ah, ok. That makes things different yet again. This is easier, though. You can make your application read a Database file directly from a CD, which you can mail to people. You should use some sort of PKI style encryption if it needs to be secure. However, due to the nature of the security requirements, I would STRONGLY suggest you contract to someone with experience with encryption, because if you implement something the wrong way, you can expose the data which would be bad :)
I would use an encrypted SQLite file.

Practical / Applied application security

Alright so here is my issue. I'm working a game engine that will eventually be multilayer. this engine allows games to be written in either a .Net language or Lua (the built in scripting engine). For security however I'd would like to prevent people from viewing these files and of course prevent them from editing them. My solution was to make a Virtual File System with encrypted headers. This way it would be difficult to discover the contents of the game data files, and if somehow someone did, they wouldn't be able to edit them without the key otherwise it would be invalid.
Another issue with the current game is that it connects to a SQL data to get certain data, this means the DB connection string and password is stored inside the application.
However, how do you deal with storing passwords inside a .Net application? I know for a fact that they can be decompiled and it wouldn't make sense to store secret keys inside a readable configuration file so how do most professionals do it?
Typically client applications do not directly connect to the database. Instead the connect to a server which handles the remote calls on behalf of the application. In such a scenario the only thing that needs the password to the database, is the server.
In modern .Net world the server is usually built using WCF

Categories

Resources