SQL Server - preventing SQL injection - sql-server

I have been looking through old posts but am seeing some conflicting info on this. I have a SQL Server database and I am talking to it with C# code (.Net 4.5). I used stored procedures to do everything in the database and parameterising the inputs when I make a call.
I would like to lock down the database so that it won't accept SQL code and will only respond to calls to the stored procedures. Is this possible?

Although there is no setting to disallow ad-hoc SQL entirely, you could grant only EXECUTE permissions on only the stored procedures called directly by application code. Permissions on objects referenced by stored procedures are not needed as long as the ownership chain is unbroken, meaning that the stored procedure and referenced schema/objects are owned by the same user (typically dbo). This method will prevent ad-hoc access by non-privileged accounts.
Be aware ownership chaining does not apply when dynamic SQL is used with the procs. If procs have dynamic SQL (with securely built SQL and parameterized), you can sign the module with a certificate to provide the needed permissions from within the proc without granting users direct permissions on objects referenced by the dynamic SQL statement. See giving permissions through stored procedures for details and examples.
Be sure to specify CommandType.StoredProcedure on all SqlCommand objects to ensure parameters must be passed separately. Although it is possible to execute stored procedures using CommandType.Text, more attention to detail is needed to do securely.

Related

How to prevent users from creating new tables/stored procedures or modifying existing procedures. SQL Server 2017

Is there a way to lock down (preferably at the server level but DB level is also fine) tables and stored procedures? I don't want specific users creating new procedures or tables, but want them to be able to write to tables (via some Excel macros we have in place) and execute existing procedures. I would not want this to be a blanket policy, I'd prefer to specify which users this applies to.
Do you have individual ms SQL server logins for every user? Then you can set the access rights of these to Datareader and datawriter only in the security section or on database level.
If everyone uses the same login, you will have to create trigger on the data definition level. E.g. a trigger on CREATE TABLE that aborts any action.
Edit: I suggest you create a new login specifically for those excel macros.

How can I allow someone to run my Oracle functions/procedures but not able to view its source codes

i have an oracle database schema with functions, stored procedures and packages. i want to allow some developers to access my tables read only so i create a user with READ ONLY access to my tables. i want to grant them EXECUTE on my stored procedures and functions but NOT allowing them to view its source (code). when i grant EXECUTE on my functions or stored procedures, they can easily DESCRIBE (in SQL developer or TOAD) and view from all_source. how do i prevent them from viewing my PL/SQL sources?
One way that I can see for this type of access is to use the package.
Create package specification and body with your procedure and grant execute on your package to other user.
Having execute rights, other user will be able to execute the procedure of the package and will be able to see only package specification and not the body (the actual code)

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

Role for read-only access to execute SP/get result set, without indirectly modifying db?

For example
if a SQL Server user account is given
only the DataReader role and ability to execute one stored
procedure that modifies data in some
way, should the execution of that
stored procedure by that user cause
the modification to occur?
Overall, I want to give one user only read ability to the entire database including use of SQL syntax, Views and to execute any store procedures that return result sets. But I don't want any side effects to cause changes in the database. Therefore in the aforementioned stored procedure example, the attempt would ideally error out to satisfy my requirement, and all similar scenarios where a side-effect might cause a change. I want to ensure my database is protected against those.
Is this doable simply at the role level?
Product: SQL Server 2005 and up
Sure you can do this. Simply create a database role at the database level, and grant that role read on the tables and execute on only the stored procedures you want (i.e. the ones that read). Then, add the desired user(s) to your database role.
However, all things considering, if you are using stored procedures to read data, do so completely and do not grant read on tables for users of any level. Drive all data access through stored procedures (and views).
EDIT: Just noticed you said SQL 2005 "and up." If you are using SQL Server 2008, look at application roles instead of the traditional database roles.

Stored Procedures access when no access in a table

All,
In SQL Server, can a stored procedure (beeing ran from a user) write to table where the user doesn't have access to write directly to the table?
Rgds,
MK
The correct answer is NO, a stored procedure does not have access to write into a table. However most users perceive it, incorrectly, as YES because of Ownership Chains:
When multiple database objects access
each other sequentially, the sequence
is known as a chain. Although such
chains do not independently exist,
when SQL Server traverses the links in
a chain, SQL Server evaluates
permissions on the constituent objects
differently than it would if it were
accessing the objects separately.
These differences have important
implications for managing security.
Ownership chaining enables managing
access to multiple objects, such as
multiple tables, by setting
permissions on one object, such as a
view.
So a procedure will be able to write into a table that the user has no permissions to write into if they form an ownership chain. This means that if the owner of the schema that contains the table is the same as the owner of the schema that contains the procedure, an ownership chain is formed and the procedure is allowed to write into the table. Since the vast majority of objects deployed in practice belong to the dbo schema, an ownership chain is almost always formed.
It is important to comprehend these details, so you can troubleshoot problems and understand why is the procedure allowed to write into the table. Erland Sommarskog has an excellent comprehensive write up on this topic: Giving Permissions through Stored Procedures. This article goes into great detail explaining all the options available. Your best option, far better than ownership chaining, is code signing.
Understanding how this works also helps understanding why dynamic SQL seems to 'break': running dynamic SQL is an automatic break in the ownership chain, which causes all 'magic' to disappear. And it also helps understand why this 'magic' appears not to work outside the database: cross db ownership chaining Option default value is 0.
In short, yes.
The main restriction in play in this scenario is whether the user can execute the stored procedure.
When creating the stored procedure, it needs to be done with a login/user that has the necessary write access to the table in question.
Yes, if the user is GRANTed EXEC permissions on the SP, any actions it takes (within that database) are allowed.
Going over to another database will require permissions on the underlying user to be examined.
Also, dynamic SQL built within the SP will require the underlying user to have permissions.

Resources