powered by simpleCommunicator - 2.0.49     © 2025 Programmizd 02
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Процедуры и функции против инъекций MySQL
9 сообщений из 9, страница 1 из 1
Процедуры и функции против инъекций MySQL
    #40098528
volosoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день! Переделываю код, хочу чтобы БД была устойчива к инъекциям.
Для тестов создал копию стандартной БД world с таблицей city, которая содержит названия городов, код страны и т.д.
Беру пример неправильно составленной процедуры и примера инъекции из учебника (адаптировал запрос под свою БД, данная процедура получает на входе буквенный код страны, а затем выдает кол-во городов этой страны из БД):

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
use test1;
drop procedure if exists proc_test_sql;
delimiter $$
create procedure proc_test_sql(in i1 char(200))
begin
    set @s=concat('select count(*) from test1.tablecity where countryCode=\'', i1, '\';');
    PREPARE stmt FROM @s;
    EXECUTE stmt;
end$$
delimiter ;



Пример добросовестного использования:
Код: plsql
1.
call proc_test_sql('rus');



Пример инъекции:

Код: plsql
1.
call proc_test_sql('rus\' or CountryCode=\'usa');



Т.е что происходит, автор создает в теле процедуры строку с запросом, которую потом использует как запрос... Потом героически пытается справиться с ситуацией, справляется, но так и не избавляется от формирования запроса в строке...
Вопрос, почему нельзя написать процедуру сразу так:

Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
use test1;
drop procedure if exists proc_test_sql;
delimiter $$
create procedure proc_test_sql(in i1 char(200))
begin
	select count(*) from test1.tablecity where countryCode=i1;
end$$
delimiter ;



Зачем мне нужно формировать запрос в строке, если я могу его сразу сформировать в теле процедуры? Разве не в этом их фишка?
И насколько я понял, такая процедура устойчива к инъекциям, сколько бы кавычек и попыток что-либо отправить в i1 не было - она всегда остается переменной. Или я не прав, и такая запись процедуры тоже уязвима?
...
Рейтинг: 0 / 0
Процедуры и функции против инъекций MySQL
    #40098539
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volosoed,

существует вариант с параметрами
https://dev.mysql.com/doc/refman/8.0/en/sql-prepared-statements.html
это раз
зачем юзеру давать структуру и поля таблиц?
это два.
...
Рейтинг: 0 / 0
Процедуры и функции против инъекций MySQL
    #40098540
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volosoed
Зачем мне нужно формировать запрос в строке, если я могу его сразу сформировать в теле процедуры? Разве не в этом их фишка?
это показано как не надо делать.
первая продемонстрированная глупость char(200) в то время как длина параметра может быть не более 3 символов

вторая продемонстрированная глупость where countryCode выборка по полю char. вместо int.
...
Рейтинг: 0 / 0
Процедуры и функции против инъекций MySQL
    #40098629
volosoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
вадя,
Спасибо, вариант с параметрами будет выглядеть так:
Код: sql
1.
2.
3.
SET @s = 'select count(*) from test1.tablecity where countryCode = ?';
PREPARE stmt FROM @s;
EXECUTE stmt USING @name;


У меня вопрос, как передать в строку запроса более одного параметра? Это вообще возможно?



вадязачем юзеру давать структуру и поля таблиц?
Вот тут немного не понял, каким образом структура и поля таблиц становятся открытыми, если записать
Код: sql
1.
select count(*) from test1.tablecity where countryCode=i1;


а не в строке запрос?
...
Рейтинг: 0 / 0
Процедуры и функции против инъекций MySQL
    #40098635
Melkij
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volosoed
У меня вопрос, как передать в строку запроса более одного параметра? Это вообще возможно?

https://dev.mysql.com/doc/refman/8.0/en/execute.html
Код: plaintext
1.
EXECUTE stmt_name
    [USING @var_name [, @var_name] ...]
синтаксис ни о чём не говорит?
...
Рейтинг: 0 / 0
Процедуры и функции против инъекций MySQL
    #40098653
volosoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Понял, вот пример добавления двух разных кодов:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
use test1;
drop procedure if exists proc_test_sql;
delimiter $$
create procedure proc_test_sql(in i1 char(200), in i2 char(200))
begin
	SET @x1=i1;
	SET @x2=i2;
	SET @s1 = 'select count(*) from test1.tablecity where CountryCode = ? or CountryCode = ?';
	PREPARE stmt1 FROM @s1;
	EXECUTE stmt1 USING @x1, @x2;
end$$
delimiter ;
call proc_test_sql('rus','chn');


Но я так и не понял преимуществ построения запроса в строке =)
...
Рейтинг: 0 / 0
Процедуры и функции против инъекций MySQL
    #40098660
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volosoed
я так и не понял преимуществ построения запроса в строке

Попробуй без этого построить сводный запрос (pivot) с динамическим набором значений...
...
Рейтинг: 0 / 0
Процедуры и функции против инъекций MySQL
    #40098724
вадя
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
volosoed
Но я так и не понял преимуществ построения запроса в строке =)
есть много разных случаев когда строка запроса заранее не определена.
какой вариант использовать - дело программиста - его опыта.
в примере вариант чисто для демонстрации. использовать его как образец для подражания нельзя.
...
Рейтинг: 0 / 0
Процедуры и функции против инъекций MySQL
    #40098898
volosoed
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо, понял.
...
Рейтинг: 0 / 0
9 сообщений из 9, страница 1 из 1
Форумы / MySQL [игнор отключен] [закрыт для гостей] / Процедуры и функции против инъекций MySQL
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]