Minimal permission for Truncate table in SSIS - sql-server

I have created several Data flows in my SSIS package that execute truncate table as part of the ETL process. I am running the package via a SQL job that is configured to use service account.
I had initially provided an ALTER authorization for that table to the service account however the DBA's have comeback saying that Alter cant be used and minimal permission need to be assigned to the service account for doing truncate.
For eg.
use CoreReferenceStaging
GRANT CONNECT,EXECUTE,SELECT,DELETE, INSERT, UPDATE,ALTER ON database::CoreReferenceStaging TO "INT\svc-w-corerefdata-qa";
ALTER AUTHORIZATION ON [PartiesIssuerCreditRating] TO "INT\svc-w-corerefdata-qa";
Currently I am having 16 stored data-flows that perform Truncate table individually.
I had initially thought of creating 16 store procedures containing Execute permissions but I feel its a maintenance issue just to call one truncate table each. Is there a better way of doing it either by assigning roles etc.
Could you let me know whats the best way to deal with this situation ?

To provide minimal permissions, encapsulate the TRUNCATE statement in a stored procedure. Either specify an EXECUTE AS clause for a database user account with the needed ALTER TABLE permission or sign the proc with a certificate based on a user with the permissions. See Erland Sommarskog's article for example scripts for the certificate, user, and TRUNCATE TABLE proc. The article also includes a detailed discussion of EXECUTE AS versus module signing to grant permissions via stored procedures.

Related

Access table indirectly, while still allowing to update the table

I plan to pass exam 'Querying Microsoft SQL Server 2012'. I would like to better understand one question.
Question is:
How would you accomplish this task?
You work as a database developer
at ABC.com. ABC.com has a SQL Server 2012 database named SalesDB with
a table named Invoices. Application developers are developing several
in-house applications that will access the Invoices table. You need to
develop a solution that will allow the applications to access the
table indirectly while still allowing them to update the Invoice
table. How would you accomplish this task?
possible answers are.
A. You should create a view on the Invoices table.
B. You should create a columnstore index on all columns used by the
applications.
C. You should allow the applications access to the Invoices table via
stored procedures.
D. You should drop and recreate the Invoices table as a partitioned
table. Possible answers are
This is source: How would you accomplish this task?
They say that correct answer is C, but I don't know why? I think that correct is A, because view works 'indirectly' with data.
Thank for help.
The commented ownership-chaining of stored procs only come into place when the stored proc and the used tables have the same owner.
So I would like to point out another argument.
You can EXECUTE a stored proc AS another user. That means you could create a user without a login and grant UPDATE permissions. Let's say the name of the user is UPDATEInvoices. When you create a stored proc you can define that it has to execute as the comtext of the user.
So, when you give the user who wants to call the stored proc EXECUTE permissions he can UPDATE rows in the table because it runs with other permissions.

SQL Server security - stored procedures

I'm trying to implement security on our applications (which consist mainly of websites using SQL Server stored procedures).
Microsoft seem to suggest that best practice is to wrap all data functionality in stored procedures which we have done. Our structure is something like:
SQL Server database - [data1]
SQL Server database - [webSPs]
PHP / Symfony web apps
All the data resides in tables in [data1] and on the same server is another 'database' which just contains the stored procedures used by the web apps.
The SQL Server has a login 'webapp' which, as a user on [webSPs], has permissions just to run the stored procedures in [webSPs].
However, as these stored procedures read, write, append data on the [data1] tables, this user has to be a member of db_datawriter and db_datareader database roles in [data1].
This all works fine, but it seems there is a hole in the security here, as its then possible for a user accessing [webSPs] to not only run the stored procedures but write to any underlying table - is it possible to give permission that say something like:
you can read/write to tables on this database but only through SPs - not directly
From what I've read, I think it would work as I hoped if there wasn't the second database which I guess is breaking ownership chaining.
Thank you in advance.
Yes, but it's frankly a pain to implement. You can use module signing. Essentially, you:
Create a certificate in your WebSps database.
Backup and restore the certificate to the data1 database
Create a user from the certificate
Grant whatever read and write permissions to the certificate-based user in data1
Sign any stored procedure you want to use cross-database with the certificate by calling the add signature syntax
Keep in mind that every time that you change the procedure (either via alter or drop and create), the signature gets lost. So you'll be in a constant cycle of re-signing. You can read more about the process of module signing here

Determing if stored procedure can execute based on AD login

I have a stored procedure that updates data in a table for a specific record. I have several users who will be making use of this stored procedure however I only want to them to be able to update records that are assigned to them.
Each record that is to be updated by the stored procedure has a field named "UserID" which define who has control over the record. I also have a mapping table that maps active directory logins to the UserID's.
I am using Active Directory so SQL Server knows who is attempting to execute the stored procedure. Is there a way within the stored procedure to look-up the users active directory login in another table and then determine if they have access to the records attempting to be updated?
You can find out who the current user is in the proc by calling SYSTEM_USER and incorporating that into the query that updates the rows.
Does this article help? Granting Row-Level Permissions in SQL Server
It recommends the following steps
Create the table, adding an additional column to store the name.
Create a view that has a WHERE clause based on the user name column. This will restrict the rows returned to those with the specified value. Use one of the built-in functions to specify a database user or login name. This eliminates the need to create different views for different users.
Create stored procedures to select, insert, update, and delete data based on the view, not the base tables. The view provides a filter that restricts the rows returned or modified.
For stored procedures that insert data, capture the user name using the same function specified in the WHERE clause of the view and insert that value into the UserName column.
Deny all permissions on the tables and views to the public role. Users will not be able to inherit permissions from other database roles, because the WHERE clause is based on user or login names, not on roles.
Grant EXECUTE on the stored procedures to database roles. Users can only access data through the stored procedures provided.
I'm no application designer but on the surface, your solution sounds unnecessarily complicated to me.
That said, you can issue the following query to get the Windows AD Login name of the user currently executing the stored procedure. You can use this information to cross reference with your mapping table to determine if the AD account has the required privileges to perform the operation.
SELECT SYSTEM_USER
Do keep in mind that this returns the name of the currently executing context, so keep in mind that this can be explicitly changed using the "Execute As" statement.
EDIT:
I wonder if perhaps a view could be used to limit the data visible to a given AD account. The Stored Procedure logic could then focus on the data modification aspect, rather than security implementation. Controlling your data access using views would also ensure that a consistent security access method is used across multiple stored procedures if required, as opposed to having to implement security checking within each.
Since writing this, the link provided by Martin Smith, details how this solution can be implemented:
Granting Row-Level Permissions in SQL Server
In conclusion, a combination of both is how Microsoft suggest you implement the solution to your problem.

sql stored procedure execution failing because of permissions on tables

Let me explain the context first.
There are two databases sitting on two distinct servers on the same network. There is a stored procedure which copies data from a table in one database to a table in the other database (the two databases have same structure, but contain different data). Users do not have permissions to query tables directly (unless their role permits them to do so), only trough stored procedures.
Now the problem.
When the stored procedure is executed by a user, it fails giving an error message that the permissions on the target table of an insert statement do not allow the user to access it. However, since the user has permission to execute the stored procedure, this should not stand in a way, should it?
an excerpt form msdn documentation:
"Stored procedures take advantage of ownership chaining to provide access to data so that users do not need to have explicit permission to access database objects. An ownership chain exists when objects that access each other sequentially are owned by the same user. For example, a stored procedure can call other stored procedures, or a stored procedure can access multiple tables. If all objects in the chain of execution have the same owner, then SQL Server only checks the EXECUTE permission for the caller, not the caller's permissions on other objects. Therefore you need to grant only EXECUTE permissions on stored procedures; you can revoke or deny all permissions on the underlying tables."
Why is the execution failing then? All the tables have the same owner.
Are you using a "OpenQuery" inside the procedure ? try using fully qualified names including the linked server.
INSERT INTO Linked_Server.Database.schema.table_name
Select .............
The stored procedure you have does it insert data into tables on both servers. Are you using a linked server and if you are does the user have permissions to do the insert into the table via the linked server as well as having permissions to execute the stored procedure?

SQL user can only run proc, but that proc can do anything

In SQL Server 2005, I want a user, called LimitedUser, to only be able to run one proc:
GRANT EXEC ON [usp_RunETL] TO [LimitedUser]
However, that proc needs to be able to do everything -- UPDATE, DELETE, INSERT, EXEC.. everything. How do I do that without having to give all those permissions to LimitedUser?
LimitedUser only needs permission to run the sproc. They don't need any other permissions.
You only need to GRANT EXEC to the limited user. As long as the user has permissions to the stored procedure, it ignores/overrides permissions for operations inside of the procedure.
I would be very careful doing this though, this sounds like a big potential security hole. Typically you would use multiple procedures to have the flexibility to adjust permissions as necessary. I would recommend to assign the permissions to the procedure, or to the underlying tables and views, rather than decide that there will be only one super procedure.

Resources