SQL Injection, dynamiczne kolumny
Możemy sobie wyobrazić sytuację gdzie do procedury jest dostarczana dynamiczna liczba lista kolumn:
Lista kolumn może mieć różną formę np: *, [kolumna], kolumna, kolumna as kol itd. Bardzo łatwo coś do takiej listy wstrzepić. Więc poproszono mnie o załatanie takich smaczków. Napisałem poniższą funkcję, której celem jest zwrócenie „bezpiecznej listy kolumn”:
CREATE FUNCTION [dbo].[SafeColumnNames] ( @fields varchar(8000) ) RETURNS varchar(8000) AS BEGIN declare @result varchar(8000); SELECT @result = CASE WHEN @result IS NULL THEN T.value ELSE @result + ',' + T.value END FROM ( SELECT CASE WHEN V.value = '*' THEN V.value WHEN V.value like '% as %' or V.value like '%]as[%' or V.value like '%]as [%' or V.value like '%] as[%' or V.value like '%] as [%' THEN (SELECT CASE WHEN ASCII(SUBSTRING(t.value,1,CHARINDEX(' as ', t.value))) = 39 or dbo.udfTrim(SUBSTRING(t.value,1,CHARINDEX(' as ', t.value))) like '' THEN dbo.udfTrim(SUBSTRING(t.value,1,CHARINDEX(' as ', t.value))) + ' as ' ELSE '[' + dbo.udfTrim(SUBSTRING(t.value,1,CHARINDEX(' as ', t.value))) + '] as ' END + '[' + dbo.udfTrim(SUBSTRING(t.value,CHARINDEX(' as ', t.value)+4,len(t.value))) + ']' FROM (SELECT dbo.udfTrim(replace(replace(V.Value,'[',' '),']',' ')) AS value) AS t) WHEN LEFT(dbo.udfTrim(V.value),1) = '[' and RIGHT(dbo.udfTrim(V.value),1) = ']' THEN dbo.udfTrim(V.value) WHEN V.value = '''' THEN '' ELSE quotename(dbo.udfTrim(V.value)) END as value FROM dbo.SplitString(@fields,',') AS V ) as T; RETURN @result END
Do działania funkcji potrzebna jest funkcja SplitString http://stackoverflow.com/a/19935594 oraz funkcja udfTrim http://www.codeproject.com/Tips/330787/LTRIM-RTRIM-doesn-t-always-work