Select permissions were revoked in SQL Server but the user can still access all tables - sql-server

I have revoked select permissions for a user in SQL Server and gave them access to one table but the user can still query all tables.
REVOKE SELECT ON "dbo"."TableName" FROM "Domain\user.name"
I have double and triple check all the permissions on both the login and user. Can someone please steer me in the right direction?

To identify all permissions someone may have in SQL, you have to look at:
The SQL Login configured for their domain login. Is it a member of any server-level groups? Does it have any server-level permissions?
What databases does it have access to?
Within those databases, what permissions does it have?
I'm guessing you've already done that. Next level:
Identify all domain groups for which SQL Logins have been created.
Determine which of these groups your user is a member of. Do the same checks as above, e.g. what can members of that group do in this SQL Instance.
Note that domain groups can contain domain groups. Depending on how in (or out of) control you Domain Administrators are, you could have crazy levels of nesting going on. And this is in the Domain, active directory, which you may or may not have sufficient access rights to review in detail.
Don't forget Local (that machine) groups, often set up by default. Is the user a member of a local machine group with elevated rights? You won't find anything out about this at the domain level.
This of course assumes that they are only using their own personal domain login, without aliasing, "Running As", SQL authenticated logins, application logins, and probably some even more obscure things I can't think of right now. (They probably aren't, unless they're griefing you.)
Note that this was off the top of my head. Configuring SQL Security is a Dark Art; figuring out who's been configured with what can be a nightmare (and worse when dealing with applications running on system accounts.) Good luck!

Related

Securing SQL Server database from Domain Admin

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.

SQL Server 2005 Security

Here is the scenario. I have a SQL Server 2005 production database/server. It currently has developers and supporters who can connect to it. I need to create a security module that gives developers read-only access to all areas of the database. This means that a developer should be able to view all objects as well as scheduled activities/jobs only.
Is it possible to enable security in this way and if so can I be gently guided on how to achieve this. I am learning to be a DBA and creating snapshots of the databases are not an option.
Thank you all in advance.
There is permission to every object.
Create a stored procedure that grant each gruop the exact permission you need on the objects you need to protect.
I'm not quite sure I follow where this "security module" will be in the architecture. Anyhow, here's one possibility that secures it from the database end.
I'm going to assume you already have users created.
Create a new role (yourdb > security > roles > new database role), say "ReadOnlyDevelopers". Make the owner dbo or whatever makes sense. Do not select any schemas to be owned by the role. Populate the "Role Members" with your developers.
Next, open the properties page on your database. Go to the permissions page. Click Add... and add the new role. Under the permissions grid at the bottom, Grant SELECT to the role.
Now assuming your developers already belong to some other role, you'll need to go into the user properties and under Database Role Membership restrict them to just the new role. At this point they should be able to just read
I'm guessing that I'm missing a detail or two (the role may need to be grated a few additional rights to "see" the database, alter passwords, etc.) but I can't get to that level of detail without setting up the entire scenario. Hopefully this pushes you in the right direction.

Windows Authentication - Restrict SQL Server Backend Access

The Problem
Good Morning! I work on an application team that supports a few applications which utilize SQL Server for data storage. Recently, our Database Support team decided that SQL Authentication was no longer permissible (for security and logging reasons) and so my team was forced to convert all connections to Windows Authentication including several dedicated Service IDs that our applications had been utilizing for data retrieval.
First, let me say there most certainly are advantages to moving to Windows Authentication, I am not trying to dispute that. But this change has raised a huge problem for us... by switching our Service IDs to Windows Authentication we have now opened up our back-end databases to every internal business user with front-end application access.
MS Access is pushed out to every user desktop and a few superusers even have access to SSMS. At this point we are relying entirely on user ignorance to prevent internal users from accessing the back-end database directly. And given that certain roles have elevated DML rights, this presents a possibility for some nasty data consequences.
This new enterprise standard has left my team stuck between a rock and a hard place at this point so we looking for any database, account or architecture solution that would allow us to restrict user access to front-end only.
Questions
Has anyone else run into this problem? Is there an architectural solution we are missing that would allow us to eliminate SQL Authentication without exposing our databases?
Does anyone know of a way to restrict access to a SQL Server database to only certain connection methods? I'm wondering if there is a way to designate a specific ID (or role) as only allowing a connection through a front end (and eliminate ODBC connections entirely).
Does anyone have any clever workarounds?
-------------EDIT---------------
A couple people brought up a good point about role access so I wanted to clarify our former and current solution... Previously, all role access was managed on the front-end and data retrieval was handled entirely by private system SQL Authenticated IDs to which end users had no visibility.
When we were forced to eliminate these SQL Auth IDs, we created a similar role-based setup on the back-end database as existed on the front end. Active Directory Groups were created to house different groups of users and these groups were assigned specific role privileges in the database. So currently access is limited by role as much as feasible.
The problem is that even the lowest privileged roles have INSERT, UPDATE and DELETE access to some tables (access which is normally controlled through code). So while we were able to mitigate risk somewhat by utilizing database roles, we still have areas where a user can bypass front end protections by logging directly into the database.
EDIT: Question clarification makes this answer obsolete, but leaving it for reference since some comments discuss it.
Assuming you mean that you have to (based on your architecture) allow access to the DB to each windows user account, one options is to use database roles.
You disable public access to your database, then define a set of database roles, depending on your use cases. Each role is granted permissions such that members of that role are able to manipulate the data they need and or work with the objects they need. Users are then mapped into the roles they require. When connecting to your database, the user will be granted permissions according to the roles they are members of.
For example, we have a role in one of our databases named MyAppUser (our name is actually related to the app which uses the db), which is designed for end users to read and insert data only. These can be created simply as follows:
CREATE ROLE [MyAppUser]
The role is granted just the permissions it to the relevant schemas or tables (assume all our "public" tables are in dbo schema for now).
GRANT SELECT ON SCHEMA::[dbo] TO [MyAppUser]
GRANT INSERT ON SCHEMA::[dbo] TO [MyAppUser]
GRANT DELETE ON SCHEMA::[dbo] TO [MyAppUser]
Each user who should have this public read-write access is then mapped into the relevant role.
ALTER ROLE [MyAppUser] ADD MEMBER [UserName]
This separates users and roles / permissions within your database and allows you to have a single point of entry to control who has access to what in your databases.
By having the "View Definition" permission denied by default (to end users), they won't be able to "explore" the database / view table definitions etc using access, or even SSMS.
NB: SSMS provides wizards for managing and viewing permissions and memberships which are very handy for getting things initially setup / tested / fiddled around with.

SQL Server Execute As Requires Individual Logins

Evening,
I would like some practical confirmation in relation to an issue we are having.
We have a K2/SourceCode solution that turns upon the successful use of EXECUTE AS with Sql Server 2008 R2.
We have no direct control over how this solution is implemented, i.e. we cannot modify the queries that are submitted to the Sql Server engine. We can, of course, capture them using Profiler, and they tend to follow this pattern:
DECLARE #cookie VARBINARY(100);
EXECUTE AS LOGIN = 'DOMAIN\username' WITH COOKIE INTO #cookie;
SELECT #cookie;
exec [dbo].[SomeStoredProcedure] /* ... various params ...*/
exec sp_executesql N'REVERT WITH COOKIE = #cookie;',N'#cookie varbinary(100)',#cookie=/* some cookie value */
So what is happening is that [SomeStoredProcedure] is being executed in the security context of the user [Domain\username], with the service (application) account impersonating that user. Again, I emphasise that we have no control over this pattern. That's what the app does.
Outwardly this behaviour is perfectly-desirable, because we want things arranged in such a way that the stored procedure is effectively executed by whichever user is at the front-end of the application at the time.
However, these queries were consistently failing, and our investigation eventually led us to this, from the Sql Server documentation (my emphasis):
Specifying a User or Login Name
The user or login name specified in EXECUTE AS must exist as a principal in
sys.database_principals or sys.server_principals, respectively, or the
EXECUTE AS statement fails. Additionally, IMPERSONATE permissions
must be granted on the principal. Unless the caller is the database
owner, or is a member of the sysadmin fixed server role, the principal
must exist even when the user is accessing the database or instance of
SQL Server through a Windows group membership. For example, assume the
following conditions: CompanyDomain\SQLUsers group has access to the
Sales database. CompanyDomain\SqlUser1 is a member of SQLUsers and,
therefore, has implicit access to the Sales database. Although
CompanyDomain\SqlUser1 has access to the database through membership
in the SQLUsers group, the statement EXECUTE AS USER =
'CompanyDomain\SqlUser1' fails because CompanyDomain\SqlUser1 does not
exist as a principal in the database. If the user is orphaned (the
associated login no longer exists), and the user was not created with
WITHOUT LOGIN, EXECUTE AS will fail for the user.
We have a group of around 30 end users who need to be able to use this application, and the requirement is that the application security account must be able to impersonate any one of those users for the execution of these stored procedures. This requirement is fixed and non-negotiable.
The above documentation seems to preclude the possibility of meeting this requirement by adding all 30 users to an AD group, adding that group as a SQL Server login, and granting the group adequate permissions. And our practical testing results support this - EXECUTE AS fails.
Take one of those Users and give them their own, individual AD login on the Sql Server and the solution will work successfully for that user. EXECUTE AS succeeds, and the necessary permissions do not need to be assigned to the individual account because they have already been assigned by way of the AD group.
So, at this point, I am reasonably confident that I know what I am going to have to do. The requirement will be that every user has to have their AD account added as an individual Sql Server Windows login.
However, before I proceed with the rigmarole of implementing this, I wanted to ask the question publicly: is there something I am missing here?
It's instructive to imagine a similar scenario on an Enterprise-scale application - this model would somewhat fall apart, because of the need to add hundreds of individual, Windows-authenticated, Sql Server logins. Setting aside the possibility of automating this process, and the administrative burden that would ultimately result, I'm just finding it a bit of a stretch to imagine that this is the only way.
I would be grateful for confirmation and/or comments.
Thanks
Robert
As no-one has responded to the contrary (or indeed at all) we have assumed that BOL is accurate, and that there is no alternative resolution.

How to secure a SQL database from domain admins?

I've got a database that I'd like to keep on the main domain, but prevent domain admins from writing to it. Read access is not a concern. To do this, it looks like I'd have to ensure any accounts with write permissions use only SQL logins (since domain admin could reset password of any other domain account). I do realize this has other security implications. Another concern is a scenario where an admin on the windows server takes the database mdf file and attaches it to another instance and modifies the database contents, then replaces the mdf on the original server. I'm first wondering if this is even possible, or will it need to be reattached through sql server?
Since the server is still on the domain, domain admins will obviously be admins on the server. Are there other ways for them to obtain write access to the database that I should be worried about (such as deleting the master database mdf)?
Wow. Big question....can I assume that you are the dba? Before proceeding, a quick disclaimer: be extremely careful about changing login permissions. Especiallly logins that are part of the sysadmin fixed server role. It could be possible to remove all logins from that role. If your server uses Windows Authentication only (or no one knows the sa password), you could lock yourself out of the sql instance. That is bad. Very bad...
Server-level logins
Domain admins and sql server sysadmins are not equivalent. If you're in SSMS, delve down into Security|Logins and expand. There may be a "BUILTIN\Administrators" login account. Double-click it to check the properties of that login. Select the "Server Roles". If the "sysadmin" server role is checked, then all domain admins have "sysadmin" privileges on your sql instance. If you uncheck it, you take that privilege away. For a domain admin (or local machine administrator) to have sysadmin privileges, they have to be explicitly added to the sysadmin server role. In earlier versions of SQL (2000 and maybe 2005), BUILTIN\Administrators was part of sysadmin by default. MS changed this in later versions because it was a security problem. If the domain admins each have their own login (ie YourDomain\JSmith), then you'd have to remove those individual logins from the sysadmin role. This will show you all the logins that are part of sysadmin: SELECT * FROM sys.syslogins WHERE sysadmin = 1
Database users
Next you need to identify which local database user is associated with the sql server login. Sysadmin logins connect as the database owner (db_owner) automatically, so you may not see any database users (other than the default ones). From SSMS, delve down into YourDbName|Security|Users and expand. Double-click a user to open the Properties dialog. The "General" page will show the login for that user. "Membership" will show the database-level roles the user belongs to. If there's a user that maps back to the network admin's sql server login, great. However, hypothetically, if you removed the BUILTIN\Administrators sql login from the sysadmin fixed server role, that login would no longer be able to connect to the database as dbo. You'd have to create a new database user and associate it with the login. Something like CREATE USER [DomainAdminUser] FOR LOGIN [BUILTIN\Administrators] Then you could start layering on permissions for the user. You only want to allow read access, right? Add the db user to fixed db role db_datareader: EXEC sp_addrolemember N'db_datawriter', 'DomainAdminUser'. If they need more permissions, add as necessary.
Something else you mentioned was the possibility of a domain admin detaching the database, attaching it to another SQL Server instance where they have sysadmin permissions, changing data within the db, then re-attaching it back to the original SQL Server instance. I'm not sure there's much you could do to safeguard against this. As a domain admin, he/she would have the ability to shut down the SQL Server NT service and grab the mdf/ldf files and do with them as they please. This seems a bit of an extreme measure to take on the domain admin's part. If this happened, it's grounds for termination, I would expect. Would they really go this far?
Lastly, the SQL Server security/permissions heirarchy is rather complex. Please don't rely on this post for all the answers. Start with some of these links and learn as much as you can.
Permissions Hierarchy (Database Engine)
Server-Level Roles
Database-Level Roles

Resources