构建动态 SQL-Server Where 子句

ber*_*d_k 6 performance sql-server sql-injection

让我们回顾一下SQL-Server 的dba.exchange Oracle 问题

这是 SaUce 的代码,经过一些格式化:

CREATE PROCEDURE GetCustomer 
    @FirstN nvarchar(20) = NULL, 
    @LastN nvarchar(20) = NULL, 
    @CUserName nvarchar(10) = NULL, 
    @CID nvarchar(15) = NULL 
as
begin 
    DECLARE @sql nvarchar(4000)

    SELECT @sql = 'C_FirstName, C_LastName, C_UserName, C_UserID 
FROM CUSTOMER
WHERE 1=1 '

    IF @FirstN IS NOT NULL 
        SELECT @sql = @sql + ' AND C_FirstName like @FirstN ' 

    IF @LastN IS NOT NULL 
        SELECT @sql = @sql + ' AND C_LastName like @LastN ' 

    IF @CUserName IS NOT NULL 
        SELECT @sql = @sql + ' AND C_UserName like @CUserName ' 

    IF @CID IS NOT NULL 
        SELECT @sql = @sql + ' AND C_UserID like @CID ' 

    EXEC sp_executesql @sql, N'@C_FirstName nvarchar(20), @C_LastName nvarchar(20), @CUserName nvarchar(10), @CID nvarchar(15)', @FirstN, @LastN, @CUserName, @CID
end
go
Run Code Online (Sandbox Code Playgroud)

SaUce 在他的第二个笔记中提到,他有 1000 行代码来防止 SQL 注入。我的感觉是他不需要这样做来屏蔽他的存储过程。

我的问题

  • 这个 SQL-Server 过程是否对 SQL-Injection 免疫
  • 它是关于性能的令人满意的解决方案。

Mar*_*ian 5

根据 Erland 的 Sommarskog关于动态 sql的文章,使用参数化查询应该是对抗 sql 注入的最佳点。关于性能,我也看没问题,因为动态sql的执行计划是从MSSQl 2005开始重用的,如果我没记错的话。仅在 sql 2000 及更早版本中,计划重用存在问题。

他接手sql注入的要点是:”

* Never run with more privileges than necessary. Users that log into an application with their own login should normally only have EXEC permissions on stored procedures. If you use dynamic SQL, it should be confined to reading operations so that users only need SELECT permissions. A web site that logs into a database should not have any elevated privileges, preferably only EXEC and (maybe) SELECT permissions. Never let the web site log in as sa!

* For web applications: never expose error messages from SQL Server to the end user.

* Always used parameterised statements. That is, in a T-SQL procedure use sp_executesql, not EXEC().
Run Code Online (Sandbox Code Playgroud)

第一点主要是一个安全措施,这样如果有一个注入孔,入侵者就不会造成那么大的伤害。第二点使攻击者的任务变得更加困难,因为他无法从尝试中获得反馈。”