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.
Related
I'm working on an application right now that requires a link to a couple of SQL Server tables. My windows network account has permission to connect to this server, but I am not going to be the only one using this application. I'm going to send it out for people to save to their PC or just put it on the company shared drive to use (I know, that's asking for problems sometimes). It's inconvenient to make a windows account for users to share because they would need to log out and in to use the app, so I was wondering if the application or ODBC connection file itself can store the credentials to access the table.
Should I configure the connection object to use something other than the windows login information (maybe a SQL server username/password), and just store the connection object in a shared location? I don't have much experience with this and haven't tried out many different solutions and I am open to suggestions.
Thank you for the suggestions
As suggested in a comment to the question, one solution would be to
create a User Group in Windows on the SQL Server,
create a SQL Server login for that group,
assign permissions within SQL Server to that login,
and then just add or remove particular Windows Users from that group as required.
That way you don't need to mess with the various SQL Server permissions for each database user, and your application can connect to the SQL Server using Windows Authentication so you don't have to mess with saved SQL Server credentials (in connection strings, or elsewhere).
You certainly can specify the username & password in the connection string -- ConnectionStrings.Com is highly recommended if you are having trouble with connection strings -- their first example for Sql Server is
Server=myServerAddress;Database=myDataBase;User Id=myUsername;Password=myPassword;
The issue is security, if users can see this in a configuration file, they can do anything that account can do. You have to handle security within you application if you do this. Most apps that handle their own security have to create users and passwords in a database table (best not to store password at all, much less plaintext -- a one way hash is recommended).
One good strategy is the create a "login user" account with well known name and password, grant no read / write, etc. for that account at all, and grant execute access to single stored proc
IsLoginPermitted #ID, #PASS
When successful, IsLoginPermitted returns the ID & PASS for subsequent use (of course these are hidden from the user) and you create your new connection string based on these.
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.
The title says it pretty well: I can access my SQL Server from the internet, and my users are configured with strong passwords to access only their respective DBs.
But I receive 10000+ login attacks by day with the user "sa".
I don't need "sa" remote access, how to disable it, and only it?
Thank you!
Security practices by Microsoft and industry state if use SQL authentication to rename the sa account and disable it. There is really no reason to use that account explicity for an application or admin account. Most companies require tracability when it comes to security and use of the sa account in SQL server does not allow for that.
Even if you disable or rename it you will still see attacks coming in for that account, it comes with the territory. The same thing occurs with the default login Oracle has in their product. Script kiddies and other hacking programs are just programmed to check for those type of accounts.
A better option might be to report where the attacks are coming from on the network side to your network team or ISP. They will be able to better handle that to block that traffic through the network layer. Just my opinion.
Perhaps this might help: in conjunction with this:
As far as i know SQL Server lets you diable single sql server logins, but that means the login is disabled in general, regardless of the machine the user is trying to connect from. So you either disable "sa" in general or you'll have give the login a really strong password. You might be able to emulate the desired behavior by using a logon trigger, that checks where the user connects from, if the user is "sa", but i think that's not a viable solution for you, since you seem to be wanting to get rid of the many connection attempts from attacks. In any case, you might want to remove "sa" from the server role "sysadmin" to guard against a potentially successful login attemt.
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.
So far, after creating DB with all the schema, all I have done so for was accessing them (tables) by reference through ConnectionStrings.
Now, twice, I've read that it's better to create a DB user and access the DB trhough that user by including him in the connectionString.
I'd like to know why so?
Thank for helping
Your question isn't that clear. It seems that you're asking if it is better to use windows security ("Integrated Security=SSPI" in the connection string) or a username/password ("User ID=myUsername;Password=myPassword;").
Its always better to use windows security. Having login information within the connection string is a security risk. Its in cleartext (unless you take some complicated steps to secure that section), and is sent across the wire as cleartext unless you set up a trusted connection between application and server.
Is it better to "create a db user and access the db trhough that user by including him in the connection string?" No. Its better to create a sql server login for user's windows identities and let them use those credentials to access the server.
You do this if you wish to connect as a specific user, rather than (for example) just using the context of the current user which your application is running under. However, if you use SQL Server authentication (i.e. username and password), you'd need to provide that password in the connection string, which is something of a security problem.
If the application has a group of anonymous users (or manages users/passwords itself) then its better to use a Windows login and run the application under a service account (which has minimal required access to the database).
If you're running an interactive application on the desktop, you should let those users connect to SQL server in their own context, by adding them to SQL Server with the required rights (e.g. db read/write , remove any higher functions). Obviously you would use groups to make administration simpler rather than adding individual users.