Sqlserver
 sql >> база данни >  >> RDS >> Sqlserver

Как трябва да предам име на таблица в съхранена процедура?

На първо място, трябва НИКОГА направете композиции на SQL команди в клиентско приложение като това, това е какво е SQL инжекция. (Добре е за администраторски инструмент, който няма собствени привилегии, но не и за приложение за споделена употреба).

На второ място, да, параметризираното извикване на съхранена процедура е едновременно по-чисто и по-безопасно.

Въпреки това , тъй като ще трябва да използвате Dynamic SQL, за да направите това, все още не искате да включите предадения низ в текста на изпълнената заявка. Вместо това искате да използвате предадения низ, за ​​да търсите имената на действителните таблици, които потребителят трябва да има право да прави заявки по пътя.

Ето един прост наивен пример:

CREATE PROC spCountAnyTableRows( @PassedTableName as NVarchar(255) ) AS
-- Counts the number of rows from any non-system Table, *SAFELY*
BEGIN
    DECLARE @ActualTableName AS NVarchar(255)

    SELECT @ActualTableName = QUOTENAME( TABLE_NAME )
    FROM INFORMATION_SCHEMA.TABLES
    WHERE TABLE_NAME = @PassedTableName

    DECLARE @sql AS NVARCHAR(MAX)
    SELECT @sql = 'SELECT COUNT(*) FROM ' + @ActualTableName + ';'

    EXEC(@SQL)
END

Някои справедливо попитаха защо това е по-безопасно. Да се ​​надяваме, че малките Боби Таблици могат да направят това по-ясно:0

Отговори на още въпроси:

  1. QUOTENAME само по себе си не е гарантирано, че е в безопасност. MS ни насърчава да го използваме, но не са дали гаранция, че не може да бъде надминат от хакери. FYI, истинската сигурност е свързана с гаранциите. Търсенето в таблицата с QUOTENAME е друга история, тя е неразбиваема.

  2. QUOTENAME не е строго необходимо за този пример, само преводът за търсене на INFORMATION_SCHEMA обикновено е достатъчен. QUOTENAME е тук, защото е добра форма за сигурност да включва пълно и правилно решение. QUOTENAME тук всъщност защитава срещу отделен, но подобен потенциален проблем, известен като латентно инжектиране .

Трябва да отбележа, че можете да направите същото с динамични имена на колони и INFORMATION_SCHEMA.COLUMNS маса.

Можете също така да заобиколите необходимостта от съхранени процедури, като вместо това използвате параметризирана SQL заявка (вижте тук:https://docs.microsoft.com/en-us/dotnet/api/system.data.sqlclient.sqlcommand.parameters?view=мрежова рамка-4.8). Но мисля, че съхранените процедури осигуряват по-управляемо и по-малко податливо на грешки средство за сигурност за случаи като този.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Проектиране на база данни:Изчисляване на салдото по сметката

  2. Как да почистя (предотвратя SQL инжектирането) динамичен SQL в SQL Server?

  3. SELECT max(x) връща null; как мога да го накарам да върне 0?

  4. Как работи функцията SOUNDEX() на SQL Server

  5. Вземете всички родители за дете