Подтвердить что ты не робот

Как параметризованные запросы помогают в SQL-инъекции?

В обоих запросах 1 и 2 текст из текстового поля вставляется в базу данных. Какое значение параметризованного запроса здесь?

  1. Передача txtTagNumber в качестве параметра запроса

    SqlCommand cmd = new SqlCommand("INSERT INTO dbo.Cars " +"VALUES(@TagNbr);" , conn);
    cmd.Parameters.Add("@TagNbr", SqlDbType.Int);
    cmd.Parameters["@TagNbr"].Value = txtTagNumber.Text;
    
  2. Преобразование txtTagNumber в целое число перед построением запроса

    int tagnumber = txtTagNumber.Text.ToInt16(); /* EDITED */
    INSERT into Cars values(tagnumber.Text); /* then is it the same? */
    

Кроме того, здесь я бы использовал проверку Регулярного выражения, чтобы остановить вставку недопустимых символов.

4b9b3361

Ответ 1

Параметрированные запросы выполняют правильную подстановку аргументов перед запуском SQL-запроса. Он полностью исключает возможность "грязного" ввода, изменяющего значение вашего запроса. То есть, если вход содержит SQL, он не может стать частью выполняемого, потому что SQL никогда не вводится в результирующий оператор.

Ответ 2

SQL-инъекция происходит, когда возможный параметр имеет sql внутри него, и строки не обрабатываются, как это должно быть

например:

var sqlquerywithoutcommand = "select * from mytable where rowname =  '" + condition+''";

а условие - строка, исходящая от пользователя в запросе. Если состояние злонамеренное например:

var sqlquerywithoutcommand = "select * from mytable where rowname =  '" + "a' ;drop table  mytable where '1=1"+"'";

вы можете запустить вредоносные скрипты.

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

вы можете быть уверены, что вне зависимости от того, что приходит в него, не будет запускать сценарии инъекций.

используя объект команды с параметрами, которые фактически выполнил sql, будет выглядеть следующим образом:

select * from mytable where rowname = 'a'';drop table mytable where 1=1'''

В сущности он будет искать строку с rowname = a '; drop table mytable, где 1 = 1' и не запускать оставшиеся script

Ответ 3

Представьте себе динамический запрос SQL

sqlQuery='SELECT * FROM custTable WHERE User=' + Username + ' AND
Pass=' + password

так что простой SQL-инъекцией будет просто ввести имя пользователя в виде ' OR 1=1-- Это фактически сделает SQL-запрос:

sqlQuery='SELECT * FROM custTable WHERE User='' OR 1=1-- ' AND PASS='
+ password

Это говорит, что выберите всех клиентов, где их имя пользователя пустое ('') или 1 = 1, что является логическим значением, равным true. Затем он использует -, чтобы закомментировать оставшуюся часть запроса. Таким образом, это будет просто распечатывать всю таблицу клиентов или делать с ней все, что вы хотите, при входе в систему он будет входить с привилегиями первого пользователя, которым часто может быть администратор.

Теперь параметризованные запросы делают это по-другому, с кодом вроде:

sqlQuery='SELECT * FROM custTable WHERE User=? AND Pass=?'

parameters.add("Пользователь", имя пользователя) parameters.add("Пароль", пароль)

где имя пользователя и пароль являются переменными, указывающими на связанные введенные имя пользователя и пароль

Сейчас вы можете подумать, что это ничего не меняет. Конечно, вы все еще можете просто вставить в поле имени пользователя что-то вроде Nobody OR 1 = 1 '-, эффективно сделав запрос:

sqlQuery='SELECT * FROM custTable WHERE User=Nobody OR 1=1'-- AND
Pass=?'

И это похоже на веский аргумент. Но вы были бы не правы.

Параметризованные запросы работают так, что sqlQuery отправляется как запрос, и база данных точно знает, что будет делать этот запрос, и только тогда она будет вводить имя пользователя и пароли просто в качестве значений. Это означает, что они не могут повлиять на запрос, потому что база данных уже знает, что будет делать запрос. Таким образом, в этом случае он будет искать имя пользователя "Nobody OR 1=1'--" и пустой пароль, который должен выдаваться ложным.

Взято из

Ответ 4

Параметрированные запросы обрабатывают все - зачем идти на поводу?

С параметризованными запросами в дополнение к общей инъекции вы получаете все обрабатываемые типы данных, числа (int и float), строки (со встроенными кавычками), даты и время (без проблем с форматированием или проблем с локализацией, когда .ToString() не вызывается с инвариантной культурой, и ваш клиент переходит к машине с и неожиданным форматом даты).

Ответ 5

Параметрированные запросы позволяют клиенту передавать данные отдельно из текста запроса. Где на большинстве свободных от текста вы будете делать валидацию + экранирование. Конечно, параметризация не помогает против другого типа инъекций, но по мере передачи параметра отдельно, они не используются в качестве текстового запроса выполнения.

Хорошей аналогией будет "недавний" бит выполнения, используемый с большинством современных процессоров и операционной системы для защиты от переполнения буфера. Он по-прежнему позволяет переполнение буфера, но предотвращает выполнение введенных данных.

Ответ 6

Понятно, почему так хочется.

sqlQuery = "select * from users where username='+username+';"

против

sqlQuery = "select * from users where [email protected];"

Оба вышеуказанных запроса, похоже, делают то же самое. Но на самом деле этого не делают.

Первый использует вход для запроса, последний решает вопрос, но только заменяет входы так же, как и во время выполнения запроса.

Чтобы быть более ясным, значения параметров расположены где-то в стеке, где хранится память переменных и используется для поиска, когда это необходимо.

Итак, если бы мы дали ' OR '1'='1 как вход в имя пользователя, первый из динамически создавал новые запросы или запросы как часть строки запроса sql sqlQuery, которая затем выполняется.

В то время как на том же входе последний будет искать ' OR '1'=' в поле username таблицы users с указанным тегом статически в строке запроса sqlQuery

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

SqlCommand command = new SqlCommand(sqlQuery,yourSqlConnection);

SqlParameter parameter = new SqlParameter();
parameter.ParameterName = "@username";
parameter.Value = "xyz";

command.Parameters.Add(parameter);