We are working on a licensing system for a client-server application where the only server component is a database (no application server). We would like to issue licenses to a particular server that cannot be installed on any other server or transferred via backup/restore. The idea is to generate a unqiue identifier via a T-SQL query and then use public/private signing to return an activation token that works only for that identifier.
Is there a way to uniquely identify a SQL Server, in a repeatable way, using only T-SQL (without a CLR stored proc or function)? For example, is there some retrievable, unique value that is created when the instance is installed?
Edit: Maybe the MAC part of NEWSEQUENTIALID() would work (see this method). If the system fails over in a cluster/failover setup, or if the primary LAN adapter is changed, it could enter a "grace period" during which it will continue to operate until re-activated on the new hardware. The question is whether this is "unique enough."
Even if you get a unique ID a potential problem is validation at T-SQL. The database is not validated. What if they hack the T-SQL and remove the activation part. Does the customer use T-SQL directly or do you have a client application. If you have a client application then why is CLR not an option. It was crack-able but I worked with an application that generated a hash of server name on the install and stored it in the database. Then the client would compare the stored hash to the dynamic hash to determine if it was on another server. Problem was if the server name was the same then it could be beat and the hash algorithm was on the client application so with effort it could be exposed.
Adian I wish I could thank you for answering my questions.
If you look in sysObjects and other systems tables/views I think you can find something to uniquely identify a server and database. Like on a restore to another server you have to delete the user and and recreate the user even though the name is the same the internal id is different. If they restored the master and application database they might be able to make everything identical but they would have to know to do that. On the base install SQL may generate a unique id somewhere as it makes sense Microsoft would want a unique id for replication, other features, and licensing.
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.
I'm writing an application to manage AD permissions groups.
However, some fields which are needed like "Primary Owner", "Secondary Owner, "Date Reviewed" and historical logs are not in AD.
I'm planning on having a separate SQL Server database to hold this data and using the Group's System ID to join the data.
My question is: Can I have the SQL Server database be synchronized with what is in AD upon changes in AD? Perhaps some listening tool exists? Can LDAP be used to solve this?
A problem which can arise if the database is updated nightly is if a new group is created in AD, primary and secondary owners need to be assigned to it, but the
SID of the new group will not be immediately in the SQL Server Database.
I'm not familiar with SQL Server, so I cannot tell whether it has some special capability to synchronize with AD.
What I know is that there are a few different solutions if you want to track changes in AD using LDAP. You can find an overview of the available techniques in this MSDN article.
I've recently open-sourced ADSync4J, a small Java library that can help you implementing the third technique mentioned in that article (Polling for Changes Using USNChanged). However it won't be of much help if your target platform is not the JVM.
We use a console application written in C# which is run on a batch to read the AD information and insert it into a SQL table. This could be done in almost any language with LDAP bindings but depending on the size of your AD catalog could be performance prohivative.
There does seem to be a way to query directly with SQL (although with some caveats, namely maximum result set size and no support for multi-value parameters). Many articles exist on this from a quick google search such as; https://www.mssqltips.com/sqlservertip/2580/querying-active-directory-data-from-sql-server/
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.
I have made an application project in Visual Studio 2008 C#, SQL Server from Visual Studio 2008.
The database has like 20 tables and many fields in each.
I have made an interface for adding deleting editing and retrieving data according to predefined needs of the users.
Now I have to
Make to project into software which I can deliver to my professor. That is, he can just double click the icon and the software simply starts. No Visual Studio 2008 needed to start the debugging.
The database will be on one powerful computer (dual core latest everything Windows XP) and the user will access it from another computer connected using LAN. I am able to change the connection string to the shared database using Visual Studio 2008/ debugger whenever the server changes but how am I supposed to do that when it's software?
There will by many clients. Am I supposed to give the same software to every one, so they all can connect to the database? How will the integrity and correctness of the database be maintained? I mean the db.mdf file will be in a folder which will be shared with read and write access. So it's not necessary that only one user will write at a time. So is there any coding for this or?
1) One option is to package and deploy your application with Installshield.
2) Have your application pull the connection string from an app config. I've seen (and done) this by having an XML file with general configuration settings (like database connection strings), that sits on the file system and is in the same directory as your executable, and is read as your executable is started.
3) Generally, SQL Server will handle most of the concurrent data reads/writes and keep the integrity of the data in-tact (as long as you've structured your tables decently).
Since you're going to deploy this app to multiple machines, it sounds like you could just install your application client on X machines, and they'll access the SQL Server database on the database machine. If you do this approach, you won't need to share the db.mdf file as it will only need to be accessible by the SQL Server, which the application will access.
I hope that helps.
The best way to maintain data integrity is to design it into the database:
You need primary keys that are formally designed.
You need primary key/foreign key relationships formally defined (and index those foreign keys; they aren't indexed automatically).
You need unique constraints on natural keys if you are using surrogate keys.
You need default values for fields that cannot be null and wehther they can allow nulls or not needs to be in the table definition.
You need the correct datatype for the type of data (do not store dates as a varchar datatype for instance).
If you have specific constraints on the values of some of your fields, then you need constraints to enforce those in the database or in the application.
how will the integrity and correctness of the database be maintained?
The database should maintain its own internal consistency using constraints.
Users should write to the database using SQL statements within a transaction, so that all related writes happen atomically (they all succeed or they all fail). Transactions also help with conflicts between users at higher levels of isolation, by maintaining locks at table, page or row level.
Update
As requested here is some code pretending to be C# (I don't use it much myself):
private Method(SqlConnection connection)
{
using (SqlTransaction transaction = connection.BeginTransaction())
{
try
{
// Use the connection here
....
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
}
If all of the statements in the try block complete successfully, they will be committed together. If any statement fails, the transaction will be rolled back, and the database won't be changed.
Strictly speaking the using statement will take care of the Rollback if the transaction isn't committed, so if you are not doing any error handling you could also write the same code like this:
private Method(SqlConnection connection)
{
using (SqlTransaction transaction = connection.BeginTransaction())
{
// Use the connection here
....
transaction.Commit();
}
}
Write an installer that copies the executable and supporting DLLs to the users computer. I believe there is an install project you can use in Visual Studio 2008.
2) You should use Windows 2000 server, Windows XP limits the number of connections. Read the connection string from the registry and provide a settings dialog to change the connection.
3) Don't use MS access, you should be using a real SQL Server that handles concurrent user access. (SQL Server, MySQL, PostgreSQL, Oracle, etc.) You need to rewrite your database access layer using SQL so you don't corrupt data.
Don't even think about deploying this project as is or you will be in for a maintenance nightmare. Are there any experienced developers or even your professor that you can ask for help? There is much to do here to make a functional application.
I’m distributing an SQL 2008 database with my c# application (only the data, which I restore in the client’s local SQL server).
Is there a way to assure that the client can only access my data by using my application? (and not, for instance, using Management Studio, SQLCMD, etc)
Thanks, Nestor
Yet another form of the same ethernal quesiton that comes up about SQL Encryption... see Who needs encryption? at the DRM section:
"I would like to package my database
application in a form that would allow
a customer to use it, but without him
ever being capable to access the
actual data stored in it. I think
encrypting the database should help".
The answer is always the same: what you ask for is DRM, not encryption, and SQL Server does not offer any DRM solution. If you your application can access the data, so can the user from any tool of his choice. You are wasting your time trying to find a solution based on SQL encryption and all the claims to the contrary are snake oil. All 'solutions' will have a key management fault that will allow an administrator to retrieve the decryption key, always.