问题
DBMS_ASSERT is one of the keys to prevent SQL injection attacks in Oracle. I tried a cursory search...is there any SQL Server 2005/2008 equivalent for this functionality?
I am looking for a specific implementation that has a counterpart of all the respective Oracle package members of DBMS_ASSERT.
- NOOP
- SIMPLE_SQL_NAME
- QUALIFIED_SQL_NAME
- SCHEMA_NAME
I know the best-practices of preventing injection...bind variables...being one of them.
But,in this question I am specifically looking for a good way to sanitize input...in scenarios where bind-variables were not used.
Do you have any specific implemetations?
Is there a library that actually is a SQL Server Port of the Oracle package?
回答1:
The only likely option you have is QUOTENAME which is used to escape object names (and thus may be an equivalent for SIMPLE_SQL_NAME or ENQUOTE_NAME and possibly others. So table names (providing they are not qualified with owner or database) and column names can be escaped.
There isn't a mechanism for fully qualifying an object (e.g., turning table 'bob' into 'database.owner.bob'), so you'd have to put this together manually, optionally using QUOTENAME to escape the values, e.g.:
QUOTENAME(@database) + '.' + QUOTENAME(@owner) + '.' + QUOTENAME(@tableName)
If the object is in the existing database, then you could use DB_NAME(), and assume that the owner's going to be passed in as a variable:
DB_NAME() + '.' + QUOTENAME(@owner) + '.' + QUOTENAME(@tablename)
In a really convoluted way, you can get owner out as well:
USER_NAME(OBJECTPROPERTY(OBJECT_ID(@tablename), 'ownerid')))
Yes I realise all of these may be considered workarounds, but they are options.
However for escaping values you really are on your own: there is no built-in SQL Server equivalent, so would be all manual string manipulation. You might be able to create a UDF to sit in place to do this, although if you're going to that effort, it's probably also worth looking at rewriting the sproc using SQL Server sp_ExecuteSQL semantics.
回答2:
Don't do dynamic queries by building strings and the EXECuting them.
Use sp_executesql and pass parameters as parameters.
You'll find that sql injection is no more.
EDIT: sorry, I was in a hurry and wrote the wrong command. it's not sp_execute, it's sp_executesql; it takes a string and a set of parameters: all the encoding and escaping of the parameters is done by SQL Server.
EDIT2: sp_executesql statement explaination
回答3:
The closest thing I have is TSQLAssert for TSQLMacro but it only supports TSQL Stored Procedures. It's free.
TSQLAssert is an assertion framework built on top of TSQLMacro. It is intended to provide debug-time assertion failures similar to assertions in languages like C++ -- with an additional logging component not found in those languages. TSQLAssert can be used only within stored procedures and triggers -- unfortunately, user-defined functions and views do not support many of the keywords that allow it to work.
回答4:
There is no magic "prevent injection" command. The methodology is a combination of:
- Using parameterized queries to ensure type safety
- Sanitize inputs before passing them to the database layer
- When you can't do 1. and 2., replace ' with '' in all input, and other sanitize methods before blindly executing dynamic SQL.
回答5:
As such there is no equivalent of DBMS_ASSERT in SQL SERVER.
However enhancing the answer of Aaron Bertrand by this link SQL Injection
回答6:
I also was once looking for something similar to DBMS_ASSERT for Sql Server, but to no avail.
So I ended up writing a collection of PROCs that we needed.
Microsoft should really ship something similar, but till then, you're on your own.
来源:https://stackoverflow.com/questions/1718388/what-is-the-sql-server-equivalent-for-oracles-dbms-assert