it-swarm-fr.com

Bâtir dynamique SQL-Server où la clause

Passons en revue cela dba.exchange Oracle question pour SQL-Server.

C'est le code de la sauce, après un petit formatage:

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

Sauce a mentionné dans sa deuxième note qu'il avait 1000 lignes de code pour prévenir l'injection SQL. Mon sentiment est qu'il n'a pas besoin de faire cela pour protéger sa procédure stockée.

Ma question

  • cette procédure SQL-Server est-elle immunisée contre l'injection SQL par elle-même?
  • est-ce comme solution satisfaisante en ce qui concerne la performance.
6
bernd_k

Selon Sommarskog's d'Erland article À propos de Dynamic SQL, l'utilisation de requêtes paramétrées doit être le meilleur point dans la lutte contre l'injection SQL. À propos de la performance, je ne vois pas non plus de problème, car le plan d'exécution de Dynamic SQL est réutilisé depuis MSSQL 2005, si je me souviens bien. Seulement en SQL 2000 et plus vieux, il y avait un problème de réutilisation du plan.

Ses points dans la prise d'injection SQL sont: "

* 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().

Le premier point est principalement une sauvegarde, de sorte que s'il y a un trou d'injection, l'intrus ne sera pas capable de faire cela beaucoup de mal. Le deuxième point rend la tâche pour l'attaquant plus difficile car il ne peut pas obtenir des commentaires de ses tentatives. "

5
Marian

Oui, cette procédure est sûre de l'injection SQL, à condition qu'elle soit appelée à partir d'une application .NET correctement paramétrée.

La performance ira bien, à condition que vous disposiez de tous les indices nécessaires en place.

4
mrdenny