Is there any way to obscure the schema of a database on SQL Server?
If I have SQL Server Express installed on a client site, is there a way to obscure the schema and data so that someone else cannot come along and learn the schema in order to extract data out of it and into another product?
The best way to obscure your database schema is to not let it leave your servers.
Even if you encrypt the schema you still will have to provide the key somewhere, and if the client is determined to get it, they'll spend time and money to do so.
So you're better off either offering your product as service or making your client loyal by doing good job.
AFAIK, "no".
The best way to "lock down" your database is:
1) Install with appropriate roles and users (ideally, SQL roles and SQL users you create)
2) Explicitly restrict object permissions in SQL Server
3) Code your application to use SQL Server stored procedures (instead of raw T-SQL) as much as possible
4) Encrypt your stored procedures
Here's a good link on "SQL Server Best Practices" that might be of interest. It discusses security issues and a (relatively) new feature, "User Schema Separation":
http://msdn.microsoft.com/en-us/library/dd283095%28v=sql.100%29.aspx
This is a tricky one and may not even be 100% possible. However, there are a few tricks to setting it up:
Install a new named instance of SQL server with a custom SA account (both name and password). There is an installation method for SQL server call "Unattended Installation" which allows you to specify all the installation parameters for SQL server in an ini file and then run the install silently. Check out the documentation here: Unattended Installation of SQL Server 2008 r2
Create your database, tables, procedures, etc. with your magic SQL install script (use encrypted stored procs if you want, but they too are crackable)
Add/Verify the schema permissions for the custom SA account and Drop all schema permissions for all Administrator roles. The goal here is that no roles have any schema permissions to your database and only your custom SA user has permission (not assigned by role, but directly to the user).
There are several commercial applications that I know of that don't even tell you they are installing an instance of MS SQL express. They too will create their own named instance with a named SA account. I can't say I like that as a customer (as SQL takes a hit on the CPU and I don't want "secret" instances running on my workstation). But so long as you disclose this to your customers upfront, they may understand.
**Keep in mind a skilled DBA may have the knowledge to mess with system tables and what not to manually grant access to your database. These techniques really are just "obfuscation" and won't be 100% bullet proof.
As a side note: With the plethora of available 3rd party datalayers and webservice technologies, I think many companies are finding their database schema alone isn't so proprietary or valuable anymore. There was a time when the database schema alone could have represented hundreds of hours of coding. But today tools like EntityFramework, NHibernate, Linq-to-SQL, XPO, etc all create your database schema for you based on your software class definitions and in code attributes. So just seeing a DB table isn't really very valuable. Plus you might write a bunch of business logic, statistical analysis or other helper methods in your software that aren't in your database schema. In my opinion, this is where today's "value add" is found, in the business logic, analysis and reporting functionality of your software - not in the raw datatables.
This is also why another poster recommended obfuscating stored procedures, because these could be many times the work of the database schema itself if you have some nice analysis and reporting procedures written up. Its also what customer's would most likely want to customize for their own reporting needs. You may be inclined to have a policy that custom reporting can only be done by your company (hey, even the big guys like SAP are sticky with who can modify what).
There is a way, it's convoluted and ugly but it works.
You have a master table that acts as a lookup table for your other tables. This master table would look sort of like this:
id, guid, entityname, parent_id
then all of your table names and column names get renamed to be guids. after that you put an entry in the lookup table for each of them. When you want to select data you have to do so by pulling the guid's out of the lookup table by their entitynames which then give you the obscured table and column names.
There is a major software vendor out there that does something very similar to this, so it has been done before.
Related
I am trying to establish a very secure table(s). As a matter of fact, I prefer the same settings to apply to all tables within the database. Basically, this database would contain sensitive information: PersonID, CreditCard, Names, Address, PINs.
Nobody has the need to query this database; NO person. The only thing that needs to access the database is the integration services during the ETL process. As a result, my strategy to "secure the database/table" is to limit the access to the table to just the service account for Integration Services in COMBINATION with using TDE (encryption at rest).
my questions are:
1) is this a good strategy? it's important not to allow anyone (including myself) to be able to query the database
2) how do I limit access to a table to just the service account in SSMS? I dont know how I can just give "SSIS" access and nobody else.
(I use SQL Server 2012 and SSIS 2012)
Thank you so much!!
I don't see how this would be a good solution. The problem is, someone could find out the password to the service user, resulting in access to everything. Also you couldn't restrict DBAs.
I would rather store all the information encrypted with a password that is not available to anyone. SSIS or whatever interface accesses the data would take on the role of encrypting and decrypting (if even needed). SQL Server also has some encryption options, if you don't have a corporate encryption method.
Also you could use a specific schema for the tables with sensitive data. You could by default deny permission to normal users for that db schema.
Does anyone have experience building database reports - doesn't matter which database - i just want design ideas - for a system that is made up of many separate, but identical databases?
I cannot "combine" all databases into one. They must be separate.
But the structure is identical across all databases...
I need to build a web interface that will allow a user to get a "global" report that will query all databases and build one combined report.
Do you have any comments on how the model would look like? or anything you think i need to beware of?
Thanks.
I don't have first hand experience with cross database reports, my experience comes from a product the company i work for sells which can create reports from multiple databases, from your description i believe you require something of the "combine" tables kind, in this case i recommend you to detect the tables used in the query, and unify them in a single temporary intermediary database, for example Access, SQL Server CE or SQLite and then run the query against this temporary database or table.
If your databases are Microsoft SQL Server, then using SQL Server Reporting Services seems like a good solution. The software for the report generation / display is bundled along with the database software.
It gives you a web interface, where you can configure 'data sources' from any number of remote databases, and combine data from these sources into reports. It is user friendly and you can do all the report design / configuration through the web interface without having to write any code.
some references :
Building report using SQL Server stored procedure
http://blog.hoegaerden.be/2009/11/10/reporting-on-data-from-stored-procedures-part-1/
I am developing a multi-tenant app. I chose the "Shared Database/Separate Schemas" approach.
My idea is to have a default schema (dbo) and when deploying this schema, to do an update on the tenants' schemas (tenantA, tenantB, tenantC); in other words, to make synchronized schemas.
How can I synchronize the schemas of tenants with the default schema?
I am using SQL Server 2008.
First thing you will need is a table or other mechanism to store the version information of the schema. If nothing else so that you can bind your application and schema together. There is nothing more painful than a version of the application against the wrong schema—failing, corrupting data, etc.
The application should reject or shutdown if its not the right version—you might get some blowback when its not right, but protects you from the really bad day when the database corrupts the valuable data.
You'll need a way to track changes such as Subversion or something else—from SQL you can export the initial schema. From here you will need a mechanism to track changes using a nice tool like SQL compare and then track the schema changes and match to an update in version number in the target database.
We keep each delta in a separate folder beneath the upgrade utility we built. This utility signs onto the server, reads the version info and then applies the transform scripts from the next version in the database until it can find no more upgrade scripts in its sub folder. This gives us the ability upgrade a database no matter how old it is to the current version. If there are data transforms unique the tenant, these are going to get tricky.
Of course you should always make a backup of the database that writes to an external file preferable with an human identifiable version number so you can find it and restore it when the script(s) go bad. And eventually it will so just plan on figuring out how to recover and restore.
I saw there is some sort of schema upgrader tool in the new VS 2010 but I haven't used it. That might also be useful to you.
There is no magic command to synchronize the schemas as far as I know. You would need to use a tool - either built in house or bought (Check out Red Gate's SQL Compare and SQL Examiner - you need to tweak them to compare different schemas).
Just synchronizing can often be tricky business though. If you added a column, do you need to also fill that column with data? If you split a column into two new columns there has to be conversion code for something like that.
My suggestion would be to very carefully track any scripts that you run against the dbo schema and make sure that they also get run against the other schemas when appropriate. You can then use a tool like SQL Compare as an occasional sanity check to look for any unexpected differences.
I have been googling a lot and I couldn't find if this even exists or I'm asking for some magic =P
Ok, so here's the deal.
I need to have a way to create a "master-structured" database which will only contain the schemas, structures, tables, store procedures, udfs, etc, everything but real data in SQL SERVER 2005 (if this is available in 2008 let me know, I could try to convince my client to pay for it =P)
Then I want to have several "children" of that master db which implement those schemas, tables, etc but each one has different data.
So when I need to create a new stored procedure or something like that, I just create it on the master database (and of course it's available on its children).
Actually I have several different databases with the same schema and different data. But the problem is to maintain congruency between them. Everytime I create a script to create some SP or add some index or whatever, I have to execute it in every database, and sometimes I could miss one =P
So let's say you have a UNIVERSE (would be the master db) and the universe has SPACES (each one represented by a child db). So the application I'm working on needs to dynamically "clone" SPACES. To do that, we have to create a new database. Nowadays I'm creating a backup of the db being cloned, restoring it as a new one and truncate the tables.
I want to be able to create a new "child" of the "master" db, which will maintain the schemas and everything, but will start with empty data.
Hope it's clear... My english is not perfect, sorry about that =P
Thanks to all!
What you really need is to version-control your database schema.
See do-you-source-control-your-databases
If you use SQL Server, I would recommend dbGhost - not expensive and does a great job of:
synchronizing 2 databases
diff-ing 2 databases
creating a database from a set of scripts (I would recommend this version).
batch support, so that you can upgrade all your databases using a single batch
You can use this infrastructure for both:
rolling development versions to test, integration and production systems
rolling your 'updated' system to multiple production deployments (especially in a hosted environment)
I would write my changes as a sql file and use OSQL or SQLCMD via a batchfile to ensure that I repeatedly executed on all the databases without thinking about it.
As an alternative I would use the VisualStudio Database Pro tools or RedGate SQL compare tools to compare and propogate the changes.
There are kludges, but the mainstream way to handle this is still to use Source Code Control (with all its other attendant benefits.) And SQL Server is increasingly SCC friendly.
Also, for many (most robust) sites it's a per-server issue as much as a per-database issue.
You can put things in master like SPs and call them from anywhere. As far as other objects like tables, you can put them in model and new databases will get them when you create a new database.
However, in order to get new tables to simply pop up in the child databases after being added to the parent, nothing.
It would be possible to create something to look through the databases and script them from a template database, and there are also commercial tools which can help discover differences between databases. You could also have a DDL trigger in the "master" database which went out and did this when you created a new table.
If you kept a nice SPACES template, you could script it out (without data) and create the new database - so there would be no need to TRUNCATE. You can script it out from SQL or an external tool.
Little trivia here. The mssqlsystemresource database works as you describe: is defined once and 'appears' in every database as the special sys schema. Unfortunately the special 'magic' needed to get this working is not available to the user databases. You'll have to use deployment techniques to keep your schema in synk. That is, apply the changes to every database as the other answers already suggested.
In theory, you could put a trigger on your UNIVERSE.sysobjects table (assuming SQL Server), and then you could enumerate master.dbo.sysdatabases to find all the child databases. If you have a special table that indicates it's a child database, you can reference child.dbo.sysobjects to find it.
Make no mistake, it would be difficult to implement. But it's one way you could do it.
It seems like something like this should exist, but I have never heard of it and would find such a utility to be incredibly useful. Many times, I develop applications that have a database backed - SQL Server or Oracle. During development, end users of the app are encouraged to test the site - I can verify this by looking for entries in the database...if there are entries, they have been testing...if not, they haven't.
What I would like is a tool/utility that would do this checking for me. I would specify the Database and connection parameters and the tool would pool the database periodically (based on values that I specify) and alert me if there was any new activity in the database (perhaps it would pop up a notification in the system tray). I could also specify multiple database scenarios to monitor in the tool. If such an app existed, I wouldn't have to manually run queries against databases for new activity. I'm aware of SQL Profiler, but when I reviewed it, it seemed like overkill for what I wanted to do (and it also wouldn't do the Oracle DB monitoring). Also, to use SQL Profiler, you have to be an admin of the database. I would need to monitor databases where I only have a read-only account.
Does someone know if such a tool exists?
Sounds like something really easy to write yourself. Just query the database schema, then do a select count(*) or select max(lastUpdateTime) query on each table and save the result. If something is different send yourself an email. JDBC in Java gives you access to the schema information in a cross-database manner. Don't know about ADO.