I would like to create a web application using PostgreSQL as a database. I want to have the database encrypted, so that even an attacker that has root access to the database server can't decrypt the data (or at least he would have to mess around with temporary in-memory data which is hard). I don't care about the schema, only about the content of the tables.
I also don't want to store the decryption key somewhere on the application server (neither in a config file, nor hardcoded).
Instead, my idea was to encrypt the whole database (or just tables and rows?) using a key that is provided by the user over the web application and that decrypts at runtime.
Is this scenario possible with PostgreSQL and which options do I have implement this?
Side note: It's a .NET based application (ASP.NET MVC3) and I'm using the Npsql driver.
Use pgcrypto for encryption. But, a superuser can control the log files and tell the database to log everything, every query. And that will include the queries including your passwords.
You might want to use SELinux and SEPostgreSQL.
Related
I have a web application in which registered users enter data in a few forms and then, when they log in at a later stage, they see forms populated with their data. Data is stored on Postgresql server of the same hosting provider of the web server.
I'd like to encrypted data stored on Postgresql to prevent them to be read by the hosting provider.
I don't think this is possible to do, because whenever is the encryption key kept, if the webserver has to access it in order to serve pages to users, then it can use it to decrypt data to read them. Anyway I preferred to ask just to be sure I'm not missing something.
You could encrypt every piece of data put into the database, but for most applications it would be impractical - slow and extremely inconvenient.
Much better option would be to use dm-crypt encrypted block device for PostgreSQL data directory. It would be transparent for a database, so all features would work fine.
But you'd have to save encryption key somewhere in the database server filesystem or your server won't start with no interaction. So malicious hosting provider can still access all your data. Even if you don't store the key in the filesystem and type it yourself while mounting a data volume, then the key would have to reside in server memory, so malicious hosting provider can still read it.
There's not much you can do - you have to trust your hosting provider somewhat. You can only make a malicious one's live a little bit harder.
Our new security policies require data access restriction for developers to the production database. Setting up -RO parameter does not work for several reasons (extracts from 'Startup command and Parameter reference' http://documentation.progress.com/output/OpenEdge102b/pdfs/dpspr/dpspr.pdf)
1) "If you use the -RO parameter when other users are updating the database, you might see invalid data, such as stale data or index entries pointing to records that have been deleted."
2) "A read-only session is essentially a single-user session. Read-only users do not share database resources (database buffers, lock table, index cursors)."
3) "When a read-only session starts, it does not check for the existence of a lock file for the database. Furthermore, a read-only user opens the database file, but not the log or before-image files.
Therefore, read-only user activity does not appear in the log file."
We would like to be able to access data on the production database from OpenEdge Architect, but not being able to edit data. Is it possible?
In most security conscious companies developers are not allowed to access production. Period. Full stop.
One thing that you could do as a compromise... if the need is to occasionally query data you could give them access to a replicated database via OpenEdge Replication Plus. This is a read-only db connection without the drawbacks of -RO. It is real-time, up to date and access is separately controlled -- you could, for instance, put the replicated db on a different server that is on a different subnet.
The short answer is no, they can't access it directly and read-only.
If you have an appserver, you could write some code which would provide a level of dynamic RO data access via appserver or webservice calls.
The other question I'd have is - what are your developers doing accessing the production database? That should be a big no-no.
I develop an app for iPhone / iPod Touch which has to have access to a MySQL database. I wrote a PHP API which I can call from the iPhone app.
In the database I store sensitive data which I want to encrypt. I think I will use AES_ENCRYPT. My problem is where to store the key.
It'd be great of you have any idea where to store the key to encrypt / decrypt so that it can not be seen by any other persons, e.g. hackers.
In general:
Don't keep your key in a part of the server that the web server has direct access to. For example, if your site is in /var/www/home, don't put your key in there. Put it someplace outside the web server's part of the tree.
Make sure that the permissions on the folder containing your key are correctly set. Your PHP app needs to have READ access only, NOT write or execute on that folder (and the key file).
Make sure the server itself has a good password (long, lots of random numbers, letters, and symbols).
Make sure the server is protected by a properly configured firewall, and is kept up to date with the most recent security patches.
As for trying to keep the key and the data separate -- this is a perennial problem for which there is no very good solution. The simple fact of the matter is that your application has to have access to the key. Either that means forcing everyone who's going to use the app to memorize the key -- which is likely to lead to sticky notes on monitors in plain view -- or else it has to live somewhere that the app can find it, either on the same server or another.
Is there a way to password protect the SQL Lite db core data uses for it's persistent store? I want to make the DB available via iTunes but I want to be password protected so only I can open it.
CoreData doesnt have any built in password protection so you are going to have to roll your own encryption or obfuscation mechanism.
Alternatives could be obscure mechanisms (press the invisible button three times?) to send the file by email for returning the data-store to you rather than exposing the Documents folder in iTunes.
I guess the question is there a genuine need for password protection (i.e personal/medical records) or is this just the usual Corporate paranoia. If its the latter I wouldn't put too much effort in. IMHO.
I am starting to build a SaaS line of business application in ASP.NET MVC2 but before I start I want to establish good architecture foundation.
I am going towards a shared database and shared schema approach because the data architecture and business logic will be quite simple and efficiency along with cost effectiveness are key issues.
To ensure good isolation of data between tenants I would like to implement the Tenant View Filter security pattern (take a look here). In order to do that my application has to impersonate different tenants (DB logins) based on the user that is logging in to the application. The login process needs to be as simple as possible (it's not going to be enterprise class software) - so a customer should only input their user name and password.
Users will access their data through their own sub-domain (using Subdomain routing) like http://tenant1.myapp.com or http://tenant2.myapp.com
What is the best way to meet this scenario?
I would also suggest using two database, a ConfigDB and a ContentDB.
The ConfigDB contains the tenant table and the hostname, databasename, sql username and sql password of the Content database for each of tenants in this table and is accessed via a seperate sql user called usrAdmin
The ContentDB contain all the application tables, segmented on the SID (or SUSER_ID) of the user and is access by each tenants sql user called usrTenantA, usrTenantB, usrTenantC etc.
To retrieve data, you connect to the ConfigDB as admin, retrieve the credentials for the appropriate client, connect to the server using the retrieved credentials and then query the database.
The reasons i did this is for horizontal scalability and the ability to isolate clients upon demand.
You can now have many ContentDBs, maybe with every ten tenants that sign up you create a new database, and configure your application to start provisioning clients in that database.
Alternatively you could provision a few sql servers, create a content DB on each and have your code provision tenants on which ever server has the lowest utilization historically.
You could also host all your regular clients on server A and B, but Server C could have tenants in their own INDIVIDUAL databases, all the multitenancy code is still there, but these clients can be told they are now more secure because of the higher isolation.
The easiest way is to have a Tenants table which contains a URL field that you match up for all queries coming through.
If a tenant can have multiple URL's, then just have an additional table like TenantAlias which maintains the multiple urls for each tenant.
Cache this table web side as it will be hit a lot; invalidate the cache whenever a value changes.
You can look at DotNetNuke. It is an open source CMS that implements this exact model. I'm using the model in a couple of our apps at it works well.
BTW, for EVERY entity in your system you'll need to have a tenantid column acquired for the above table.