Securing SQL Server database from Domain Admin - sql-server

I have inherited a SQL Server box with a series of databases and it has Windows Auth for creation/maintaining the well-baked and established databases. The box itself has many other services which require a user to login as admin to maintain.
I now have to create a new database on the server that only a select few in the company, including IT, will have access to. So I'm kind of chasing my tail on the best place to start.
I want to continue to give the guys the admin level access they require to all the other stuff on this box but limit them on SQL Server options so I can better manage the databases and secure them. What might be the best way to unwind the Windows Authentication method and dole out databases / create opportunities for those users while securing new databases they should not access? Am I even going in the right direction by deviating from the Windows Auth method?

One of the primary reasons for creating a second instance on a server is security. By creating a second instance you basically re-start security over again. So this is an option you might consider for your new database. IE Creating a second instance and putting the "secure" database on it.
A few things you should also consider.
First, yes you should unwind your security as possible and give out the minimum security required for any given user/group. This is a best practices thing. Never give out dbo or sysadmin permissions without an explicit reason to do so, and even then question it thoroughly to make sure that there isn't some other way around the problem. Never give out more permissions than are absolutely required.
Second, It is almost impossible to keep the administrator of the server the instance is on out of the instance if they really really want to get in. And I only say "almost" impossible because there may be a way that I don't know about. At the level of administrator for the server, or domain administrator for that matter you have to assume they can be trusted not to try to break in. You probably won't be able to keep them out anyway.
Last but not least if you can move your instance off of a server that has many other services which require a user to login as admin to maintain. This is a security nightmare first of all (as I said above) and second your SQL server will work better on it's own server. I've even heard advice from experts that say you should never remote into the server a SQL Server instance is on. And if you have to remote in definitely don't copy files around while remoted. Generally said the less going on on the server the happier SQL is.

You can remove the domain administrators ability to access the SQL Server by removing the BUILTIN\Administrators group from the SQL Server logins.
I wouldn't recommend moving away from Windows Authentication, as you would create a whole new set of security concerns you then would have to deal with.

Domain admins can
add themselves to any group (local or domain) that has has access to SQL Server
change the service account policies and log in with that
change SQL server to use a service account in case it uses a built in account
use any user account that has SQL Server access
change password to allow this
Do anything in the domain. At. All.
SQL Server always has Window Auth switched on so it is always available to Domain Admins
If it's that sensitive then it needs to be in separate domain or standalone or something.

Related

Make Azure Firewall Rules Automatically Expire

Caveat: Ok, so this might not be necessary, but my standard security mentality is to make things as hard as possible, and then ease up as required.
Right now, I'm the sole developer for a software system that is based in Azure (SQL Server and Mobile Service).
Although the entire system is designed to access its SQL Server databases using the Azure Mobile Service API, I'm using SSMS to administer the database during development and testing, and I've had to create a Firewall rule to allow this access. If this project expands (which looks likely in the next few months), I'll need to give other DB admins/developers access to some of the same resources. That's fine, but given the sensitive nature of some of the data we will be housing, I'd like to automatically invalidate those Azure SQL Server firewall rules at the end of the day. I realize that this will require their re-creation at the start of each business day. I am ok with this.
From what I've read, there appear to be 3 different ways to manage Azure SQL Server firewall rules programmatically:
T-SQL (sp_delete_firewall_rule)
REST API (DELETE to https://management.core...)
Azure Powershell (Remove-AzureSqlDatabaseServerFirewallRule)
I don't really care how it gets done, but I'm already using a Mobile Service Scheduler job to expire password reset tokens (totally unrelated to the current task), so I thought I would give that technique a shot.
Here was that attempt:
function ClearSqlServerFirewalls() {
var sql = 'Exec sp_delete_firewall_rule ?';
mssql.query(sql, ['name'], {
success: function (results) {
console.log(results);
}
});
}
In a not-terribly-surprising outcome, I got the following error:
User must be in the master database.
Ok, so that makes good sense, given that this is a system-wide effect, not a database-specific one. Azure apparently creates a specific SQL user for each database and runs all Mobile Service code through that user. Since that user doesn't have database-wide access, no dice.
So, here are my current thoughts on this:
SQL Agent apparently doesn't exist for SQL Azure, so automating the T-SQL script from within SQL Server appears to be out.
I don't yet know of a way to automate the REST API call from within Azure itself.
I am not familiar with Powershell in Azure.
Is there any way to do what I want to do? Giving the Azure user access to the master database (if even possible) seems like a bad solution.
Yes, I realize this may seem like overkill, but if I have the right credentials, I can add an IP rule for just about anywhere. Say I'm on a working lunch and need access. I add the rule and get to work. But say I forget about that rule, it could potentially just sit out there as an open invitation to someone who gets on that same network. I realize that this is slightly paranoid, but it just also seems logical to me that a firewall rule would be able to come with a built-in expiration. Am I missing something?
I think that the good way to do that would be to use Azure Automation for PowerShell commandlets - it can be scheduled, for example, once a day, and you can build a full Powershell management pipeline.
https://azure.microsoft.com/en-us/documentation/articles/sql-database-firewall-configure/
Take a look at the cloud-based graphical tool as well:
https://blogs.endjin.com/2016/03/using-azure-automation-to-run-vms-during-office-hours-only-using-graphical-runbooks/
Basically, you will need to change the main part to the SQL Azure commandlets.
If that is the helpful answer, please mark it as a helpful or as the answer. Thanks!

Application vs SQL server 2008 accounts issue

Good day all,
I am studing the following case:
Scenario: An application connects to the production database(SQL server 2008) using a generic "SA" user instead of the domain user. This is making traces\logs\organization harder, because everything is flagged as done by SA user!
NOTE: In the application the domain user/password is used, the generic account is only regarding to the database.
Questions: What would be the best pratice in this case? every user should have an account to log in the database? (sql using windows authentication) there are +- 500 users is that an issue regarding to database performance? or a generic account is indicated?
Many thanks!
As others have mentioned, Active Directory and Windows Authentication might be more appropriate if that's an option. But if not...
If the application has a central place that creates the connection & transaction prior to update, you may be able to use SET CONTEXT_INFO to pass along the "real" application user while still using a shared SQL account for the login.
Then in your auditing triggers you can pull the information back out again using the CONTEXT_INFO() function
This is the approach used by at least one commercial auditing tool
See also similar SO questions here and here which reference context_info and a blog post Exploiting Context_Info for Fun and Audit which gives an NHibernate example.
Nitpick on something else in your question: you said it's using sa user. Maybe that was just an example, but probably the application should not have so many rights on the server. Create a user with only the rights needed for the particular database(s) that application uses. This limits the impact of any future security vulnerability (e.g. SQL Injection) in your application. And to take it one step further, you might have one connection string with a read-only user account, and then at the point where you create a transaction to update data, switch to a connection string with the read/write user account. You still get most of the benefits of connection pooling, but you limit even further the impact of any application-tier bugs.

Security issues with allowing anonymous users to create SQL Server login and accounts?

I have a rich client program installed on users PCs where I want to start storing some user created data on SQL Azure/SQL Server. The potential anonymous-to-me users would key in their name, email account and a password which would get stored on SQL Azure/SQL Server. Then they would start generating their own data. I'm anticipating volumes of maybe 1000 users.
There are times when those users would like to run their own queries against their own data but, obviously, I must ensure that they can never view other users data.
I'm thinking the best way to ensure security of data is for each user to be issued their own SQL Azure account and password. I will setup a SQL Azure user and long password, known only to me, which only has permissions to execute several stored procedures with appropriate parameters being passed to those SPs which will create the SQL Server accounts, logins and add the users to a role which I have created.
Obviously someone running debugging tools could figure out the user name and password but I'm thinking this isn't a big deal. If all that particular SQL Azure account can do is execute a few SPs so what if a malicious individual starts doing that. I will only allow a very limited amount of data to be uploaded before I require payment.
The users can only insert records using stored procedures which use the following:
SELECT #uName=SYSTEM_USER
and only select appropriate parent records. All stored procedures which users can execute would have the above as required to ensure they can only work with their own records.
All views will have embedded with them WHERE clauses such as
WHERE tbLoginName = SYSTEM_USER.
I'm new to SQL Server so I may be missing some fundamental concepts so I'd appreciate any and all comments.
The issue is, as pointed out on http://msdn.microsoft.com/en-us/library/ms189751.aspx:
In SQL Azure, only the server-level principal login (created by the provisioning process) or members of the loginmanager database role in the master database can create new logins.
Those accounts are also capable of alter and drop logins. So if you embed those accounts in the client application, you’re essentially granting every user permission to alter/drop other users accounts. While an average user won’t do that, a hacker will. So you cannot let a client application manage SQL Azure logins, unless only trusted users (such as your IT administrator) are permitted to use the app.
Best Regards,
Ming Xu.
I would like to point out a potential issue in the approach you mentioned: Your master SQL Azure account need to have privilege to create new accounts and grant them access to particular tables. This means your master account itself need to also have access to all those tables. If you store the master account on the client side, a clever user will get access to all users data.
From my experience, connecting to a database directly from a client side application will almost always make your solution less secure. You can do that for testing purposes, but in a real world solution, I would like to suggest you to use a service. You can host the service in Windows Azure. Then the service will access the database, and client application can only access the service. In this way, you can authenticate clients using any mechanisms you like, such as ASP.NET membership.
Best Regards,
Ming Xu.
You are essentially creating a physical two-tier database connection, allowing a client application to connect directly to the database. This is a problem in many ways, including security and performance. From a security standpoint, not controlling from where your customers will connect, you will need to keep your firewall rule wide open for anyone in the world to try to hack every customer uid/pwd. And instead of having only 1 user id to play with, hackers will have up to 1,000...
The second issue is performance. You applications will be unable to leverage connection pooling, creating undue stress on your database server and possibly hitting throttling issues at some point. Using a web service, with ASP.NET membership to manage logins, and using a service account (i.e. the same uid/pwd) to get data will ensure you will leverage connection pooling correctly if you keep the connection string the same for all your requests.
With a web service layer you also have a whole slew of new options at your fingertips that a two-tier architecture can't offer. This includes centralizing your business and data access logic, adding caching for improved performance, adding auditing in a centralized location, allowing to make updates to parts of your applications without redeploying anything at your customer locations and so much more...
In the cloud, you are much better off leveraging web services.
My 2 cents.

SQL Server Login role for remote database manipulation

My scenarion is MVC Blog (funnelweb) installed on a server named WEB. The SQL Server 2005 runs on DB. FunnelWeb site requires access to its own database. I have create a new database using SQL Server Management Studio and had named it FunnelWeb. I want to use SQL authentication, so I went ahead and created a SQL login FunnelWebAdmin. In the login mappings I have mapped FunnelWebAdmin to FunnelWeb database, and have granted him a dbowner permission on a db. I have not granted a login any server roles.
SQL Authentication is enabled for the server.
My question is:
Do I need to grant this login any server roles, so that the web site can connect to a database using SQL authentication? If yes, which are the minimum one's in order for site to be able to manipulate database.
Unless I'm missing something setting that user in the role DBAdmin will give it the right to login. It will give it full rights and control over the database.
Be sure you lock down that web application. Giving admin rights to a DB from a web app is dangerous at best. It leaves you open to SQL injection, which can open the door to all sorts of issues. A good attacker (or a mediocre one with access to google) can exploit an SQL Injection attack and gain full control over the operating system if the server isn't locked down properly. http://sqlmap.sourceforge.net/doc/BlackHat-Europe-09-Damele-A-G-Advanced-SQL-injection-whitepaper.pdf
Even if they can't get control over the OS, you still need to worry about data theft, insertion of XSS or XSRF scripts, or any number of attacks.
I'm not saying not to do it, just to be careful and be sure you know what you're doing. Getting access to a database via a web app is childs play if there are any vulnerabilities. There are toolkits that you can buy that do it for you, so attackers don't even need to know what they're doing.
I really have no idea what your experience level is, so forgive me if I'm telling you something you already know. Your question indicates that you're more on the "beginner" end of the spectrum, but I may be wrong.
Assuming I'm right, however, I would really caution you to spend a lot of time on these sites,learning everything you can. They don't teach this stuff adequately in school, or in the "Learning programming" resources (books, web, videos, etc).
OWASP Top 10
Writing Secure Code (Microsoft)
Even if the website itself is not Internet accessible (say it's running on a corporate Intranet and only logged in users have access) you still need to be cautious. Statistics show that disgruntled co-workers with access are just as much of a threat as outside attackers. Just something to bear in mind.

SQL Server Login Configuration and Automation

What's a good way to manage and maintain SQL Server logins, server roles, and individual access rights across multiple databases that exist in multiple environments? What are your best practices?
Some info about my situation:
SQL Server 2005
We have N amount of "client" databases with identical schemas (in theory, at least)
We have a central "admin" database that references each client database and can hold configuration values
This "admin/client" pattern is duplicated across multiple environments (dev/qa/stage/prod)
Some users, like testers, need different rights based on evironment
We frequently have to pull client db backups from one environment to restore on another for development or testing purposes
We keep our stored procedures and scripts in source control and deploy in a build cycle
Right now my organization is chaotic and we don't follow good security practices. We have no formal DBA. However, if we got any more complex it would be a constant hassle to maintain it all the time. I could see migrating to a new server or recovering from disaster being extremely time consuming if we where to attempt configuring it directly through the management studio IDE.
First, to make restoring a database to a different server easier, make sure that your logins all have the same SID on all of your servers by using the sp_help_revlogin stored procedure from Microsoft to script the login on the first server you create it on and then use the script to create the login on your other servers. This keeps the database user mapped to the login correctly when you restore the database.
Having different permissions at the database level depending on the environment is going to be a hassle to a point no matter how you role this out. I have a stored procedure in master that gets called on my Dev Server as a part of my restore process that performs the additional GRANT's on the database to give the developers access to make changes. That's the best I have been able to come up with to solve similar problems.
A way to make the rights easier would be to create rolls in the database called Dev, QA, Test, Prod and grant the correct rights to those roles. Then as you restore the databases to each environment just drop the developers in the correct role.
We use active directory groups and enforce windows authenticated logins. From within SQL Server we can then define access based on the AD group the user is in by creating a single SQL Server login per AD group. Not sure if this is any better or worse than DB roles, but it means the roles are managed outside each database.
Propagating access to databases is then either a manual operation or a short SQL script to ensure the logins in the database point to a valid SQL Server login (which in turn is an AD group).
Generally this works well for the general case. We can use DB roles then to assign the builtin roles (e.g, db_datareader) to each AD group
Rarely someone needs some specific access to a database outside this model. We either end up opening it up to the group as a whole if it's not going to be invasive or critical or we'll end up creating a per-user account that has to be managed separately. We endevour to keep these to an absolute minimum, and clean them up every now and then so they're not abused/forgotten about.

Resources