Как защитить запросы с параметризованными именами таблиц от внедрения - PullRequest
0 голосов
/ 23 мая 2019

Ища способ взаимодействия с данными в разных таблицах на одном сервере, я наткнулся на решение, предложенное по этому вопросу .Насколько я смог найти, нет другого способа «передать» имя таблицы в запрос.Проблема в том, что он кажется уязвимым для SQL-инъекций;например, я мог бы использовать этот код для добавления кого-либо в таблицу «Student» в базе данных с именем «School1»:

CREATE PROCEDURE AddStudent (
    @DBName char(10), 
    @FirstName char(30), 
    @LastName char(30)
    ) AS
DECLARE @SqlScript varchar(MAX) = '
    INSERT INTO ' + @DBName + '.dbo.student (FirstName, LastName) VALUES (' +
        @FirstName + ', ' + @LastName + ');'
EXECUTE (@SqlScript)

Когда я вызываю хранимую процедуру «AddStudent», я просто передаю переменные «School1»',' Бобби 'и' Столы '.Вы можете увидеть, к чему это приведет ...

Даже если имя базы данных каким-то образом программно (и, следовательно, безопасно) определяется клиентской стороной, маленькие Бобби Таблицы могут выбрать использовать его полное имя ииспортить вещи с @FirstName = Роберт , @LastName = ');DROP TABLE студент; - вызывает у нас всевозможные проблемы.

Конечно, это может быть маловероятным и экстремальным примером, но вы получите картину.Есть ли способ предотвратить это?

1 Ответ

0 голосов
/ 23 мая 2019

Дейл упомянул, что мне потребуется отдельная хранимая процедура для каждой базы данных, что дало мне идею разбить ее на две отдельные; тот, который только определяет, какую базу данных использовать, а затем передает значения другой, которая фактически добавляет студенческую запись. Это не особенно элегантно, но позволяет вам многое делать в SQL:

Во-первых, запрос, который добавляет учащегося, именно так, как вы ожидаете, - поместите его в каждую из баз данных:

CREATE Procedure [dbo].[AddStudent] (@FirstName char(10), @LastName char(10)) AS
    INSERT INTO SCHOOL1.dbo.Student (FirstName, LastName) VALUES
        (@FirstName, @LastName);

Затем еще один, который может находиться в основной базе данных или, альтернативно, в каждой из баз данных, в зависимости от того, что наиболее удобно отправлять на:

CREATE Procedure [dbo].[AddStudentUniversal] (@DbName char(10), @FirstName char(10), @LastName char(10)) AS
    IF (@DbName = 'SCHOOL1')  EXECUTE SCHOOL1.dbo.AddStudent @FirstName, @LastName
    IF (@DbName = 'SCHOOL2')  EXECUTE SCHOOL2.dbo.AddStudent @FirstName, @LastName
...