database access impersonation - sql-server

My objective is to prevent direct user access to the database server. One way is to create a WCF service or web service in the middle between the front end application and the database server.
First of all, the users will be authenticated to the application. Subsequently the application will connect through the WCF service to perform business logic operations. The WCF service will perform the database related operations by using one windows account. This will prevent other users to directly access the database server, since the permission will only be granted to specific one windows account.
Here are my questions : Even though the database access is only granted to one windows account and the WCF will use this windows account to perform database related operations, is it possible to mark all database related operations with the credential of the logged in user ?
Update
Thanks for the replies. Seems like the above scenario is not achievable. I am currently exploring the SQL 2008 Application Role feature. One of the example is here. But after further exploration, apparently there is an issue with the connection pooling.
Update
There is a stack overflow thread here regarding SQL Server Application Role

You'd have to have every user set up in sys.server_principals to enable context switching like EXECUTE AS which would mean that they have direct db access anyway.
If you enabled kerberos/delegation, the same applies. Links One and Two
You'd have to pass in the user name as a parameter on each SQL call, or use CONTEXT_INFO perhaps.
Note: every MS Office user has MSQRY32.EXE which acts as a query tool. If you want no direct DB access, then you need to ensure there are no permissions set or granted

Depends.
If your database and WCF service are on the same box and you do a lot of jiggery pokery to impersonate then it is possible. As soon as you move your DB to another box then it stops working.
This is a known limitation and the reason is impersonation will create a token which will get you to a box but this is not passable to another box. I tried to find the Q&A where MS guy had answered but still havent been able to. Whenever I find it, will update.

Related

Settings per connected user

I have an windows forms application which I'm migrating from MySql to MsSql. In MySql we are using database users for every user. So every user connects to the database using their own account. This is not what we want, because in the future we want the application set open to the world and database users is not a thing on the wishlist. So this is going away.
The problem is that many views work with a function which uses CURRENT_USER() to give access to records (because users are part of a department and are not allowed to see all records of all departments).
In MsSql we are using just one type of connectionstring, but every application connects the database directly. Is it possible in MSSQL to store variables per connection so I can identify a user in the view by the variable I set after creating the connection?
So it would be like this:
Start application
Users logs on
Application creates connection with mssql
Application sets a variables on sql-server
User opens a screen with a view
SQL server returns the view using the variable that has ben set earlier to only return the allowed records to view.
So every user must have it's own variable. Is that possible?
Application is build with NET and iBatis. Not the best combination, but iBatis is to much integrated to throw it all overboard.
While this may or may not be possible, it's definitely not the right way to go. As you said, you're using a single connection string, and likely using a pool of connections to access the database. As you want users to be able to pick any available connection in the pool to do their queries, you don't want any user state (or any state at all for that matter) to be tied to the connection.
As you're opening up to the world, you don't want the application to directly connect to the database. Instead, you should implement middleware that will handle authentication and access rights, and only return data from the database that the user may access. So instead of
user application <- iBatis -> MSSQL
you'll have:
user application <- HTTP/something else -> API <- iBatis -> MSSQL
This is the approach taken used by websites as well. In addition, you'll be able to add functionality like caching, connection pooling etc. to the API, making it possible to support more users.

Allow remote connection only for specific users

I just enabled remote connections on my SQL Server Express 2012 installation. Now I am a little bit worried about the server security because allowing connections to everybody sounds like a big security hole for me.
Is it possible to tell the SQL Server to disconnect if the user is trying to authenticate with a user which is not on my "allow" list? If so, I could add my monitoring user to this list and don't have to worry that my administration accounts are accessible.
First of all, this is probably a question that should be asked in the DBA site. Anyway, you can set up the security of the server so that only certain users are allowed to login.
When you set up the server, you add Logins to the Server Level and then Users at the database level. Only the users that are setup can, obviously, use a particular database. You can place users into roles, so, for example, they will have read-only access to a database. You can control, down to the object level, who has access to what.
There is a good article on what SQL Server security is about here
Having said that, sometimes, after, you have setup your security, you need to disallow certain users to not be allowed to Logon. Perhaps you are doing some major upgrade to the database. One option in this case is to create a Logon trigger.
A Logon Trigger will fire every time a user Logs in. You could create a table of "allowed" users and, in the trigger, if they are not in the table you ROLLBACK, effectively disallowing the Logon.
Here is information about creating a Logon trigger
You should be able to set up the db server to only accept connections from certain IP addresses, rather than to all of them. I'm unsure of the T-SQL syntax, but someone will surely chime in with the correct one.
If you really mean business, that being said, you'll want to authenticate clients using certificates that you give them. See this and the various articles it links to:
https://security.stackexchange.com/questions/14589/advantages-of-client-certificates-for-client-authentication
Being able to connect remotely to a SQL Server instance does not mean that they can Login to it. If they are not authorized properly, they should still get kicked-off by the SQL Server Login Authentication sequence.
This is silent/invisible for "Trusted Logins" (where the authorization comes from their Windows Login/Domain Account), but it still happens.
If you look under the "Security" folder of your Server (in SSMS), you will see the list of authorized Logins to you SQL Server. By adding or removing these you can control who can actually create a session on your SQL Server.

SQL Server Integrated Security

I've been searching hard to get my head around security related issues in a SQL Server.
We're developing a .NET application that targets SQL Server 2008 and we want to use FileStream.
Now I've found out that SQL Server only allows FileStream through the Win32 API if you use Integrated Security. The problem is that we have around 80% of our application finished, but it is entirely based on SQL Authentication. So we are doing INSERT's straight form our application and are not using Stored Procedures for every CRUD operation.
This is relatively safe because I can store the the SQL username and password in an encrypted form. I know the password is transported in Clear Text, but I'm willing to accept that.
We want end-users to be able to connect to the databse through tools such as Crystal Reports and for that we have an extra SQL login that has only SELECT-rights granted.
Now, if we change to Integrated Security we would have to give individual users (via AD groups, etc.) rights to do the things the application can do. Otherwise the application would not be able to do it's work. But then the end-user would also have these rights when he connects straight to the DB.
I see people saying that you should use Stored Procedures for every CRUD operation and grant the EXEC-rights only to the AD-group, but how would I do this? I do not see how a user would have different authorizations when he connects directly or through the application... Can anybody enlighten me on this.
An extra question for bonus-points: Intergrated Security will not work on a Workgroup as far as I understand. How do people get FileStream to work in a Workgroup then? Or is this considered an impossibility?
Integrated security WILL work in a workgroup, using the legacy mechanism, where you have a matching username and password on the two machines. Also, a domain user can use the legacy mechanism to log into a non-domain server if the server has a matching user account.
Integrated security can even work with non-matching usernames and passwords. This may help you in your scenario.
Try this:
NET USE \\DBSERVER /USER:DOMAIN\USERNAME
You will be prompted for your password. This establishes a NetBIOS session with the database server. You should be able to see the shared folders and shared printers on the database server once you have done that.
Once a netbios session has been established between the client computer and the database server, you will THEN be able to use integrated security without being prompted for a password.
You may have to specify "named pipes" as the network protocol to usem, if it doesn't work with TCP (but I think it will). Named Pipes inherits your existing NetBIOS session, so provided you can list the shares you are probably good to go.
You can also establish the logon session using the windows API function NetUseAdd with USE_INFO_2 (level 2) information which incorporates the password.
I guess the short answer then is that you can have a special Windows logon for your application and have the users log in using that. However note that they cannot also be connected to the same server using their own username and password.

SQL Server Windows Authentication Security

We have an application that uses Windows authentication to authenticate users with the database, and the SQL Server user accounts need to have certain read/write access to database tables.
The trouble is that the users can then install SQL Server Management Studio and potentially use the database in ways it's not supposed to be used, which isn't what I want.
Everything that I have read says that using integrated authentication is more secure but at the moment, any user can use Management Studio or Access/Excel to just connect to the database.
I have read question SQL Server Authentication or Integrated Security?, which suggests some workarounds, but I don't really have the option of changing the app as drastically as re-factoring all of the stored procedures etc. so I was hoping there might be another option?
Thank you,
NIco
Everything that I have read says that
using integrated authentication is
more secure
--> It's more secure in a way because it's more difficult to get the password.
If you use SQL Server authentication, the connection string contains user and password. If you know where the connection string is (often in a config file), you can open it and see user and password.
On the other hand, if you use Windows authentication, the connection string just says "Integrated Security=True" and you connect to the server with your Windows account, with the actual password buried somewhere deep in Windows' guts and more difficult to retrieve.
Of course, the big downside of Windows authentication is that if your users need write permissions on a certain table for your application, this means that they can write to the same table with ANY other application as well.
There are some workarounds, but none of them is THE silver bullet:
If your app only needs certain tables of the DB, you can just give permissions on these. So at least, the users can't do stuff in all the other tables
If the users are not allowed to access any tables at all from outside your application, there are unfortunately only two things you can do:
Change your app to SQL authentication and remove all permissions for Windows users
(you can also use a proxy service like Will Hughes suggested, but the effect is the same when the app accesses the DB directly...the point is that your users' Windows accounts don't have any permissions anymore!)
Create views and stored procedures (if they don't already exist anyway) for the stuff your app can do with the database. Give the users permissions to use these, and remove the permissions to the real tables.
--> the users can access the views and SPs directly with other tools (even if they don't have any permissions on the underlying tables...permissions on the views and SPs are enough), but they can't do anything that they can't do in your app as well.
If you don't want users to have access to your database, don't grant them access.
If you need to control what they can do - then you should do your access control in a webservice (or some other form of proxy service), which will then execute approved queries, return data, etc.

SQL Server authentication - limit access to database to only connect through application

I have a database which users should not be able to alter data in unless they use the specific app. I know best practice is to use windows authentication however that would mean that users could then connect to the database using any other data enabled app and change values which would then not be audited.
Unfortunately SQL 2008 with its inbuilt auditing is not available.
Any ideas how to ensure that users cannot change anything unless its through the controlling app?
Use whatever means for users to log in. Windwos authentication encouraged.
make sure the user has no rights to change any data ;)
The application then, on the existing connection, post-authorized using application roles.
More info on that is on http://msdn.microsoft.com/en-us/library/bb669062.aspx
Basically the application can get a separate sets of rights by using an application password (that sadly has to be coded into the application - use sensible means to protect it), replacing the limited rights the user has with more rights for itself.
I would ask you to consider using an application server, but if you have a classical client/server architecture that is as good as it gets.

Resources