I have a VB6 application that connects to a MySQL DB. The username and the password are in the source code. The problem is that when I open the .exe file in a hex editor the username and the password are both visible.
Can you suggest a solution so that the username and the password would be no longer visible?
Thanks
As long as those credentials are in your application, someone with a little knowledge can find and read them.
If you encrypt that information, you'll need to decrypt it at some point. So you'll either need the decryption key in the app - so people can read it too, rendering the whole thing moot - or you'll be decrypting server-side - in which case anyone else could just send the encrypted credentials as well.
So here's a tip: don't base the security of your application on having some secret buried within the code. You'll just be presenting script kiddies with an interesting challenge.
You really need a middle tier.
Wherever practical you want to avoid sharing the database credentials with clients. Ideally you don't even want firewalls to allow database connections from outside.
Client/server DBMS connection protocols are not optimal for use across the Internet anyway.
These are all reasons why the "web service" concept came about, and was being used even before the phrase had been coined.
Of course that still leaves you with the need for credentials at the client. I'd handle this by storing them externally so that they can be updated. You might also want to use two stages of decryption in your programs so that you can divide the process up, making it harder to reverse engineer from decompiled/disassembled code. Do one stage early in initialization and the other later, or do stage two just prior to making your connection.
Related
On a lot of public webpages, hosted by people at their own homes, they use their own desktops as webserver. Within this kind of setting usually I use a form of server sided language (like php) that connects to an MySQL server on the same machine. When installing this I always give an password to the “root” user and create a new user and password for the application (the php) script to use. Because both script and database are on the same “localhost” I always set the allowed connection to only allow connections from the local host and not from anywhere else. So both “root” and other “users” can only connect from when accessed from within the machine.
(the separate “root” and “user” accounts are made to give them separate privileges and an user can not drop scheme’s for example)
Today it struck me, why am I setting passwords in MySQL? Because if you want to connect to this database you already have to been logged in in the local machine. So, is setting passwords really necessary or just a redundant precaution?
And if it’s NOT an redundant precaution, why is it unsafe to not set a password.
(not that it is a big burden, but I have to remember all these passwords somehow, using encrypted systems this is not a real big problem, but if it could be avoided than……)
The comments on your post have mostly summed this up, but as far as I am aware, this is known as "Defense in depth" (See 1 and 2). Defense in depth is basically about avoiding having a single point of failure in your project - If your webserver is compromised, having a weak password means that you're just giving away your database for free. This would be equivalent to somebody breaking into your house to find you've placed your safe on the kitchen table and unlocked it.
If you're hosting an externally facing website that you hope to get a decent amount of traffic, making it as secure as possible is a good idea, unless you particularly like the idea of malicious users having direct access to your home network. That said, if you are expecting a decent amount of traffic I highly recommend hosting your website elsewhere - You may find that your home internet speeds suffer greatly as a result.
This is a similar question to "Storing MS SQL Server credentials in a MySQL Database"
So, in theory, imagine I have 1 MySQL server. I have a "master" database, and then X number of other generic databases. What im looking for, is a way of using an app (for arguments sake, lets say a web app, running on php) to first access the master database. This database then needs to tell the app which database to connect to - in the process, giving it all the credentials and username etc.
How is the best way around this?
The three ideas I have so far
Store the credentials in the master database for all the other databases. These credentials would of course be encrypted in some way, AES probably. The app would get the encrypted credentials, decrypt, connect.
Store the credentials elsewhere - maybe a completely separate server. When the master database is accessed, it returns some sort of token, which can be used to access the credential storage. Again, encrypted via AES.
Using some sort of system that I am not aware of to do exactly this.
Not doing this at all, and come up with a completely different approach.
To give a little example. "master" would contain a list of clients. Each client would contain it's own separate database, with it's own permissions etc.
I've had no reason to do this kind of thing myself but your first two ideas sound good to me and (as long as you include server address) not even necessarily separate ideas (could have some clients on the server with master, and some elsewhere) the client logic won't need to care. The only issue I can see is keeping the data in the "master" schema synced with the server's security data. Also, I wouldn't bother keeping database permissions in the master schema as I would think all clients have the same permissions, just specific to their schema. If you have "permissions" (settings) that limit what specific clients can do (perhaps limited by contract/features paid for), I would think it would be much easier to keep those in that clients' schema but where their db user cannot change data.
Edit: It is a decent idea to have separate database users in this kind of situation; it will let you worry less about queries from one user's client inadvertently (or perhaps maliciously) modifying another's (client account should only have permissions to access their own schema.) It would probably be a good idea to keep the code for the "master" coordination (and connection) somewhat segregated from the client code base to prevent accidental leaking of access to that database into the client code; even if encrypted you probably don't want them to even have any more access than necessary to your client connection info.
I did something like this not long ago. It sounds like you're trying to build some kind of one-database-per-tenant multi-tenant system.
Storing encrypted credentials in a directory database is fine, since there's really no fundamentally different way to do it. At some point, you need to worry about storing some secret (your encryption key) no matter what you do.
In my use case, I was able to get away with a setup where the directory just mapped tenants to db-hosts. The database name and credentials for each tenant were derived from the tenant's identifier (a string). So something like, given a TenantID T:
host = whatever the directory says.
dbname = "db_" + T
dbuser = T
dbpass = sha1("some secret string" + T)
From a security standpoint, this is no better (actually a bit worse) than storing AES encrypted credentials in the directory database, since if someone owns your app server, they can learn everything either way. But it's pretty good, and easy to implement.
This is also nice because you can think about extending the idea a bit and get rid of the directory server entirely and write some function that maps your tenant-id to one of N database hosts. That works great until you add or remove db servers, and then you need to handle shuffling things around. See how memcache works, for example.
You can use Vault to do this in much systematic way. In fact this is a strong use-case for this.
Percona has already written a great blog on it,
Firstly to explain, we have some websites which all connect to a central database. As a rule we don't give clients access to the FTP for their website so they cant access any files with the DB credentials in them. 99.9% of the time this is fine.
However we are having a client insisting they have full FTP access. They want to add advertising / tracking stuff in, and I have set them up their own database and a locked down FTP in another directory, but thats not good enough apparently.
Now I am sure they don't intend to steal our mysql credentials and connect and wipe out our DB's but no doubt you will agree its a huge security risk.
Is there any way to:
a) connect to the database without them seeing the credentials within the code
b) stopping them from adding their own code and connecting to the central database, only their own
Pretty sure nothing is going to be 100% secure, as giving them FTP access means they can do the same as I can, but wondering if anyone else has any ideas?
The only way to do this "securely" without writing a RESTful API (which you've indicated is not feasible), is to create for them a special user account in your MySQL, that cannot access records not owned by them. Truthfully you should do this for all your clients if you're doing it "right," although I understand that can be a lot of maintenance.
Regarding encryption, there isn't a way to encrypt your DB credentials for the client and have them decrypted for the DB login without some intermediary code. This shouldn't matter though if the client has their own MySQL account for access.
For people that still are looking for some solutions I found a nice tutorial on how to make credentials more safe. The author proposes to create additional layer encrypting password and decrypting within app.
https://maciejzalwert.medium.com/quick-tip-for-developers-to-protect-against-credentials-leak-b203a4d80b3b
Let's say that you have a standalone application (a Java application in my case) and that this application has a configuration file (a XML file in my case) where you store the credentials (user and password) for a bunch of databases you need to connect.
Everything works great, but now you discover (or your are given a new requirement like me) that you have to put this application in a different server and that you can't have these credentials in the configuration files because of security and/or compliance considerations.
I'm considering to use data sources hosted in the application server (a WAS server), but I think this could have poor performance and maybe it's not the best approach since I'm connecting from a standalone application.
I was also considering to use some sort of encryption, but I would like to keep things as simple as possible.
How would you handle this case? Where would you put these credentials or protect them from being compromised? Or how would you connect to your databases in this scenario?
I was also considering to use some
sort of encryption, but I would like
to keep things as simple as possible.
Take a look at the Java Cryptography Architecture - Password Based Encryption. The concept is fairly straight forward, you encrypt/decrypt the XML stream with a key derived from a user password prior to (de)serializing the file.
I'm only guessing at what your security/compliance considerations require, but definitely some things to consider:
Require strong passwords.
Try to minimize the amount of time that you leave the sensitive material decrypted.
At runtime, handle sensitive material carefully - don't leave it exposed in a global object; instead, try to reduce the scope of sensitive material as much as possible. For example, encapsulate all decrypted data as private in a single class.
Think about how you should handle the case where the password to the configuration file is lost. Perhaps its simple in that you can just create a new config file?
Require both a strong password and a user keyfile to access the configuration file. That would leave it up to the user to store the keyfile safely; and if either piece of information is accidentally exposed, it's still useless without both.
While this is probably overkill, I highly recommend taking a look at Applied Cryptography by Bruce Schneier. It provides a great look into the realm of crypto.
if your standalone application runs in a large business or enterprise, it's likely that they're using the Lightweight Directory Access Protocol, or LDAP, for their passwords.
You might want to consider using an LDAP, or providing hooks in your application for a corporate LDAP.
I'm considering to use data sources hosted in the application server (a WAS server), but I think this could have poor performance and maybe it's not the best approach since I'm connecting from a standalone application.
In contrary, those datasources are usually connection pooled datasources and it should just enhance DB connecting performance since connecting is per saldo the most expensive task.
Have you tested/benchmarked it?
there's this interesting problem i can not solve myself. I will be very glad, if you help me.
Here's it:
there are many client applications that send data records to one MySQL server.
Few data records are not very important, but the whole database is. (You can imagine it is facebook DB :) )
Is there any way to ensure that
data from DB won't be used by anyone but true owner
DB will preserve essential features such as sorting etc.
assuming that attacker can mysteriously gain full access to server?
You can't simply encrypt data client-side and store it encrypted, since client application is wide-spread and attacker can get key from it.
Maybe adding some layers between application and DB, or combining encryption methods client- and server-side (using mysql built-in methods) will help?
As long as the database needs to start up and run unattended you can't hide the keys from a compromised root account (= 'mysterious full access'). Anywhere the database could possibly store the master key(s), the root will also have access. No amount of business layers or combination of client-server encryption will ever circumvent this simple fact. You can obfuscate it till the day after but if the prize is worth then root can get it.
One alternative is to require a manually assisted start up process, ie. a human enters the master key password during the server boot (or hardware module PIN), but this is extremely hard to maintain in real world, it requires a highly trusted employee to be on pager call to log in and start the database whenever there is downtime.
Solutions like TPM offer protection against physical loss of the server, but not against a compromised root.
Your root is as important as the database master key(s), so you must protect your root with the same care as the keys. This means setting up operating procedures, screening who has access to root, rotating the root password and so on and so forth. The moment someone gains 'mysteriously full access' the game is pretty much lost.
I pretty much agree with Remus Rusanu's answer.
Maintaining good security is hard, but you can always pay attention to what you do. When ever you access sensitive information carefully verify your query and make sure it cannot be spoofed or exploited to gain access to information which shouldn't be accessible by given client.
If you can roll out physical access to the box by the attacker then there are several things you can do to harden your security. First of all I'd configure ssh access only to only allow connections from specific IP or IP range (and of course no root access). You can also do that that on your firewall. This would mean that the weakest link is your server (the application which receives data/requests from clients, could be web-server and whatever scripts you use). Now you "just" have to make sure that no one can exploit your server. There are a lot more things you could do to harden your system, but it think it would be more appropriate to ask on ServerFault.
If you're worried about physical access to the PC, there isn't really much you can do and most stuff has already been mentioned in Remus answer.
There's also another option. This is by far the most ineffective method from speed and ease to develop viewpoint, but it would partly protect you from any kind of an attack on your server (including physical). It's actually quite simple, but a bit hard to implement - only store the encrypted data in the database and handle all encryption/decryption client-side using javascript or flash. Only the client will have the key and data will always be transfered over the wire and stored in encrypted format. The biggest drawback is that once client forgets the key there's no way back, the data is inaccessible.
Of course it's all matter of time, money and effort - with enough of these anything can be broken.
I've no idea if such a thing exists in MySql, but row-level-versioning in Oracle enables you to define access rights on row-level IN the database: so that means, regardless of what tool is being used to access the data, the user only ever sees the same selection as determined by his/her credentials.
So if my username/role is only allowed to see data limited by some WHERE clause, that can appended to each and every SELECT that appears in the database, regardless of whether it comes from a web app, a SQL querying tool, or whatever.
I will use a 2nd layer and a firwall between them.
so you have firewall ---- web server --- firewall -- 2nd layer server --- firewll --- db
it will be wise to use different platfroms between layers, it all depends how important is the data.
anyway - the web server should have no access to DB.
about preserving sort - if you use a file encrypotion mechisim - it will only protect you from Hard drive theaft.
if you encrypt the data it self, and if you do it smartly (storing the keys in a separate place) you will not loose sorting as you will look for the encryoted entry and not the real one- but now you have another thing to protect....