sql >> Databasteknik >  >> RDS >> Sqlserver

Hur rengör (förhindrar SQL-injektion) dynamisk SQL i SQL Server?

Jag tror att det finns tre olika fall som du måste oroa dig för:

  • strängar (allt som kräver citattecken):'''' + replace(@string, '''', '''''') + ''''
  • namn (allt där citattecken inte är tillåtna):quotename(@string)
  • saker som inte kan citeras:detta kräver vitlista

Obs :Allt i en strängvariabel (char , varchar , nchar , nvarchar , etc.) som kommer från användarkontrollerade källor måste använda någon av ovanstående metoder. Det betyder att även saker du förväntar dig att vara siffror citeras om de lagras i strängvariabler.

För mer information, se Microsoft Magazine (Föråldrad länk:2016-10-19) .

Här är ett exempel med alla tre metoderna:

EXEC 'SELECT * FROM Employee WHERE Salary > ''' +
     REPLACE(@salary, '''', '''''') +   -- replacing quotes even for numeric data
     ''' ORDER BY ' + QUOTENAME(@sort_col) + ' ' +  -- quoting a name
     CASE @sort_dir WHEN 'DESC' THEN 'DESC' END     -- whitelisting

Observera också att genom att göra alla strängoperationer inline i EXEC påstående att det inte finns någon oro för trunkeringsproblem. Om du tilldelar mellanresultaten till variabler, måste du se till att variablerna är tillräckligt stora för att hålla resultaten. Om du gör SET @result = QUOTENAME(@name) du bör definiera @result för att innehålla minst 258 (2 * 128 + 2) tecken. Om du gör SET @result = REPLACE(@str, '''', '''''') du bör definiera @result vara dubbelt så stor som @str (anta varje tecken i @str kan vara ett citat). Och naturligtvis måste strängvariabeln som innehåller den slutliga SQL-satsen vara tillräckligt stor för att rymma all statisk SQL plus alla resultatvariabler.



  1. SQL Server Azure / 2022 Databas Ledger Tables från Linux.

  2. Använd MySQL relationsdatabaser på Ubuntu 10.10 (Maverick)

  3. Oracle TNS-namn visas inte när ny anslutning läggs till SQL Developer

  4. FORALL-uttalande med VALUES-OF Bound-klausul i Oracle Database