Is there a way to hide the definition of a SQL Server stored procedure from a SQL admin? - sql

I've been asked to hide the definition of several SQL Server stored procedures and initially looked at the WITH ENCRYPTION option but from what I can tell a fellow admin can simply decrypt this.
Is there anyway to hide the definition even from other admins with sa privileges?

There is no way.
If you are a member of the sysadmin role, you can decrypt the sql modules easily, for example by using this tool: https://www.devart.com/dbforge/sql/sqldecryptor/
It needs access to one of two things:
The Dedicated Admin Connection
DBCC PAGE
A sysadmin has access to both. Even if you explicitly deny their use, they can just re-grant themselves.
However, you can audit their use. Once you have that setup, the rest is a matter of the contract between you and the vendor. If you set this up correctly (ask your lawyer), they should have no incentive to even try.

Related

Run xp_create_subdir without admin privilidges

The Point: I want to be able to create a directory on the filesystem through a non-sysadmin SQL user.
I'm creating a web front-end for a deployment script which creates new databases from a specified template database.
Essentially I'm backing up said template database and then restoring this as a brand new database with a different name.
Our DB server has our client databases stored in sub-folders within our database store. If I were to use the default settings it would look something like:
D:\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\[ClientRef]\[ClientRef].mdf
D:\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\[ClientRef]\[ClientRef].ldf
I only have SQL access to the database server (via a programming language, hosted on a separate box) so I can't execute anything other than SQL.
My database user is extremely limited, however I would like to somehow grant this user to access/execute master.dbo.xp_create_subdir only. Is this possible at all?
I'm loathe to give our local DB user sys-admin rights, it has a limited user for a reason.
DB Server is Microsoft SQL Server 2008 R2.
Cheers, any help will be appreciated.
One possible solution is to write your own sproc that internally uses master.dbo.xp_create_subdir.
Create the sproc while logged in as an account that's a member of the sysadmin role and use "WITH EXECUTE AS SELF". Then grant permissions to that other account to execute this sproc. The database catalog where you create this wrapper-sproc must be marked as "trustworthy" or you'll still get the: User must be a member of 'sysadmin' server role. error.
E.g.
CREATE PROCEDURE [dbo].[sprocAssureDirectory] #directoryFullPath varchar(4000)
WITH EXECUTE AS SELF
AS
BEGIN
EXEC master.dbo.xp_create_subdir #directoryFullPath;
END
Just make sure you add any needed assertions/checks to your sproc that make sense for your application (e.g. the path can only be of a pattern that you expect).
Belated Update: Added the critical mention of marking the catalog as trustworthy.
You could give access for the user to use that stored proc explicitly. It is gonna be something like:
GRANT EXECUTE ON OBJECT::master.dbo.xp_create_subdir
TO <SQL USER>;
It sounds like that user is limited for a reason though and getting the extra permissions to run something like that can get a little push back from whoever is managing the DB. So be careful when dealing with getting the elevated privledges.

Impersonation denied from trustworthy database

I am using EXECUTE AS to allow a least-privilege user to run some SQL stored procedures as a sysadmin. I know that I need TRUSTWORTHY=ON on the source database (the one running the stored procedures) in order to impersonate the sysadmin on other databases on my server. However, even with impersonation granted and TRUSTWORTHY=ON, I still get the following error when trying to touch other databases as the impersonated user:
The server principal [least_privileged user] is not able to access the database XXX under the current security context.
(And yes, I know that module signing is the more secure option. I'm not looking to go that route.)
Can anyone help me?
Use execute as owner.
Make sure the procedure is in the dbo schema.
Make sure the database owner has sysadmin rights on the instance. I
have noticed that SQL logins work better for this purpose than ones
from Windows.
Check trustworthy=on for the database.
This way, you don't need additional impersonation grants, but it is a way less secure solution. It will work, though.

How can I allow SQL Injection safely

So I wanted to know if there is an acceptable method to Allow SQL Injection.
Example:
Limit permissions on the table(s)/database(s)
Why you ask?
My employer wanted to devise a way to test the skills of applicants, one suggestion was to allow resume submissions via SQL Injection.
Any thoughts? suggestions?
You could use roles. Create a role for the web application (or whatever) that is used to connect to the database. Limit this role to only permit INSERT and access to necessary tables for applying. Applicants with access to your database through the application could then only use SQL injections to add their resume.
It may be possible for someone more talented in SQL to use injections in a way that increases the role's permission. But I think if the role had limited access to only specific tables and didn't have CREATE or GRANT privileges, the user wouldn't be able to create new roles.
Here is some information on roles to get you started:
Adding Roles to MySQL with MySQL Workbench
Creating Roles in PostgreSQL
GRANT command - used to add privileges to users on table, database, etc. This page is for PostgreSQL, but MySQL is very similar (see this SO answer)
Given that the reason behind this is to test people's ability, create a database with data you can afford to lose. Set up a form that posts to a coldfusion or php or java or .net or some other type of page which connects to that database.
On the form, put a textarea and submit button. On the form target page, log what they put in the textarea. Compare the log to the database to see how it turned out.
Then test to your heart's delight.

View server login permission

I've been working on giving a development team the ability to have read-only access to a SQL environment, I'm at the last step. I need them to be able to see users/logins and roles. I noticed that with view defintion granted on any given DB, it allows their login to view the users/roles for each DB, however even granted on master/msdb/model it does not allow the login to view the server wide logins/roles. What would be the best way to accomplish this? I have tried view defintion and I have tried view server state, neither has worked for server logins to be visible to the user.
Note: I don't want them to have any more access beyond that so I don't want them to be assigned a predefined role.
I'd recommend writing a stored procedure using Execute As permissions, and giving them permissions to run that. Have that stored proc output the list of users and you should be good to go.
I am not a db admin but i read an article related to setting security / permissions using schemas in sql server 2012. I tested a little for setting permissions to some views.
This might help http://msdn.microsoft.com/en-us/library/dd283095.aspx

Best practice on users/roles on SQL Server for a web application

I searched online a bit and couldn't find anything that really nailed the spot or covered the bases how to go about setting up users/roles on a database.
Basically, there would be a user that would be used to access the database from the application (web application in this case) that will need access to database for the regular database operations (select, insert, update, delete) and executing stored procedures (with exec to run stored procedures within other stored procedures/UDFs).
Then, we would also have a user that would be main admin (this is simple enough).
I currently have a development environment where we don't really manage the security too well in my opinion (application uses a user with db_owner role, though it is an intranet application). Even though it is an intranet application, we still have security in mind and would like to see what are some of the ways developers set up the users/roles for this type of environment.
EDIT: Web application and SQL Server reside on separate machines.
EDIT: Forgot to mention that an ORM is used that would need direct read/write access.
Question:
What are the "best practices" on setting up the user for application access? What roles would apply and what are some of the catches?
First, I tend to encapsulate permissions in database roles rather than attach them to single user principals. The big win here is roles are part of your database, so you can completely script security then tell the deployment types to "add a user and add him to this role" and they aren't fighting SQL permission boogeymen. Furthermore, this keeps things clean enough that you can avoid developing in db_owner mode and feel alot better about yourself--as well as practice like you play and generally avoid any issues.
Insofar as applying permissions for that role, I tend to cast the net wider these days, especially if one is using ORMs and handling security through the application. In T-SQL terms, it looks like this:
GRANT SELECT, UPDATE, INSERT, DELETE, EXECUTE on SCHEMA::DBO to [My DB Role]
This might seem a bit scary at first, but it really isn't -- that role can't do anything other than manipulate data. No access to extended procs or system procs or granting user access, etc. The other big advantage is that changing the schema--like adding a table or a procedure--requires no further security work so long as you remain within that schema.
Another thing to take into consideration for SQL 2005+ is to use database schemas to secure groups of objects. Now, the big trick here is that many ORMs and migration tools don't like them, but if you render the default schema [dbo] to the app, you can use alternative schemas for special secured stuff. Eg--create an ADMIN schema for special, brutal database cleanup procedures that should be manually run by admins. Or even a separate schema for a special, highly secured part of the application that needs more granular DB permissions.
Insofar as wiring in users where you have separate boxes, even without a domain you can use Windows authentication (in Sql Server terms integrated authentication). Just make a user with the same credentials (user/pass combo) on both boxes. Setup an app domain to run as that user on the web box and setup a Sql Server user backed by that principal on the sql box and profit. That said, using the database roles can pretty much divorce you from this decision as the deployment types should be able to handle creating sql users and modifying connection strings as required.
For a long time the SQL Server guidelines for application access to the database were to isolate access to data into stored procedures, group procedures into a schema and grant execute on the schema to the principal used by the application. Ownership chaining would guarantee data access to the procedure callers. The access can be reviewed by inspecting the stored procedures. This is a simple model, easy to understand, design, deploy and manage. Use of stored procedure can leverage code signing, the most granular and powerfull access control method, and the only one that is tamper evident (signature is lost if procedure is altered).
The problem is that every bit of technology comming out from the Visual Studio designers flies in the face of this recommendation. Developers are presented with models that are just hard to use exclusively with stored procedures. Developers love to design their class models first and generate the table structure from the logical model. The procedure based guidelines reuire the procedures to exists first, before the first line of the application is written, and this is actually problematic in development due to the iterative way of modern development. This is not unsolvable, as long as the team leadership is aware of the issue and addresses it (ie. have the procedures ready, even as mocks, when the dev cycle starts).
Create a user 'webuser' that the web application uses.
Only grant stored proc execute permissions to this user. Do not allow direct table read/write. If you need to read something from a table, write a proc. If you need to write data, write another proc.
This way everything is kept nice and simple. One app user, with only the relevant permissions. If security is compromised, then all the intruder can do is run the procs.