sql >> Databáze >  >> RDS >> Sqlserver

Jak vyčistit (zabránit vkládání SQL) dynamickému SQL v SQL Server?

Věřím, že existují tři různé případy, kterých se musíte obávat:

  • řetězce (vše, co vyžaduje uvozovky):'''' + replace(@string, '''', '''''') + ''''
  • jména (vše, kde nejsou povoleny uvozovky):quotename(@string)
  • věci, které nelze citovat:to vyžaduje přidání na seznam povolených

Poznámka :Vše v řetězcové proměnné (char , varchar , nchar , nvarchar , atd.), který pochází z uživatelsky ovládaných zdrojů, musí použít jednu z výše uvedených metod. To znamená, že i věci, o kterých očekáváte, že budou čísly, budou uvozovány, pokud jsou uloženy v řetězcových proměnných.

Další podrobnosti najdete v Magazínu Microsoftu (Zastaralý odkaz:2016-10-19) .

Zde je příklad použití všech tří metod:

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

Všimněte si také, že provedete všechny operace s řetězci inline v EXEC prohlášení, že problémy se zkrácením se netýkají. Pokud mezivýsledky přiřadíte proměnným, musíte ujistěte se, že proměnné jsou dostatečně velké, aby udržely výsledky. Pokud to uděláte SET @result = QUOTENAME(@name) měli byste definovat @result pojmout alespoň 258 (2 * 128 + 2) znaků. Pokud provedete SET @result = REPLACE(@str, '''', '''''') měli byste definovat @result být dvakrát větší než @str (předpokládejme každý znak v @str může to být citace). A samozřejmě řetězcová proměnná obsahující konečný příkaz SQL musí být dostatečně velká, aby pojala všechny statické SQL plus všechny výsledné proměnné.



  1. Vkládání dat SQL Server pomocí Oracle® SQL*Loader

  2. Oracle - aktualizace join - tabulka bez klíčů

  3. Spojení vnořených smyček a výkonové cívky

  4. Průvodce návrhem databáze pro hlasování a průzkum v MySQL