Вопрос

Я хотел бы знать, защищен ли я от SQL-инъекции, когда я использую что-то подобное с PostgresSQL:

CREATE or REPLACE FUNCTION sp_list_name( VARCHAR )
RETURNS SETOF v_player AS '
   DECLARE
      v_start_name ALIAS FOR $1;
      r_player  v_player%ROWTYPE;
      v_temp VARCHAR;
   BEGIN
      v_temp := v_start_name || ''%'';
      FOR r_player IN
         SELECT first_name, last_name FROM v_player WHERE last_name like v_temp
      LOOP
         RETURN NEXT r_player;
      END LOOP;
      RETURN;
   END;
' LANGUAGE 'plpgsql' VOLATILE;

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

select * from sp_list_name( 'A' );

дает мне игроков с фамилиями , начинающимися на A.

Я попытался внедрить sql с помощью

select * from sp_list_name( 'A; delete from t_player;--' );
select * from sp_list_name( '''; delete from t_player;--' );

Я в безопасности ?

В каком случае мне можно было бы сделать инъекцию ?

С уважением

Это было полезно?

Решение

С точки зрения вашей процедуры вы кажетесь безопасными, поскольку переменная в SP не будет расширена в код, но вы все равно можете раскрыть себя, если не используете параметризованный запрос типа "SELECT * FROM sp_list_name(?);" в твоем код приложения.Что - то вроде "SELECT * FROM sp_list_name('$start_name');" может быть нарушен пользователем , передающим начальное имя "');delete from t_player where last_name NOT IN ('".Поэтому используйте параметризованный запрос или проверьте правильность ваших входных данных в вашей программе.

ПРИМЕЧАНИЕ: Для других, пожалуйста, обратите внимание, что переменная в хранимой процедуре будет не разверните в код, даже если он содержит ' или ;, (исключая передачу его в ВЫПОЛНИТЬ, для чего вы бы использовали quote_literal, не скрученный вручную replace функции), таким образом, заменяя ;or ' совершенно не нужен (в хранимой процедуре приложение, использующее его, конечно, - это совсем другая история) и помешал бы вам всегда находить "tl;dr" или "O'Grady" команды.

Лео Мур, Карл, LFSR Consulting: v_temp_name в хранимой процедуре будет НЕ быть расширен в код в SP (нет ВЫПОЛНИТЬ), проверка должна была бы выполняться в приложении, а не в SP (или вместо этого OP мог бы просто использовать параметризованный запрос в коде своего приложения).То, что предлагают другие, похоже на беспокойство о

my $bar = "foo; unlink('/etc/password');"; 
my $baz = $bar;

фактически выполняется отсоединение при отсутствии оценки.

Другие советы

Правило №1 для предотвращения sql-инъекции:Очистите все входные данные, поступающие от кого-то / чего-то, чему вы не можете доверять / не имеете контроля.

Сама проблема кроется не в коде базы данных, а в приложении, которое выполняет эти инструкции.

Правильный способ защиты от SQL-инъекции - это Белый список* - длинный и короткий - это набор символов, которые вы собираетесь принимать, и их фильтрация.

Неправильный способ заключается в том, чтобы Черный список - Черный список персонажей, которые не принимаются, приведет к неприятностям, потому что ты не можешь не отставайте от нападающих.Есть способы обойти черные списки с помощью таблиц ASCII, escape-символов и прочего.

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

* В приложении, а не в базе данных (спасибо Джеймсу)

Вы не генерируете SQL для себя, так что это выглядит безопасным (для меня).

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

Ссылка.Белый список.Это нормально, если соблюдаются определенные другие условия.Абсолютно необходимо разбить весь ввод на простейшую форму, поэтому не просто проверяйте имена SQL-запросов, одинарные кавычки и т.д.Они могут быть представлены или закодированы с использованием других наборов символов, и именно это является частью белого списка, а не самих ключевых слов SQL.

Я работал на конкретного клиента, который разрешил использовать имя пользователя / пароль к защищенному ресурсу (что в конечном итоге могло бы дать вам пропуск в защищенные части аэропорта!).Вы могли бы обойти поле входа в систему, введя ' и затем создав оттуда SQL-запросы для извлечения учетных записей пользователей и паролей.

Проблема заключалась в том, что клиент уже потратил 200 тысяч фунтов стерлингов на создание сайта с поставщиком, который, похоже, никогда раньше не занимался веб-разработкой.Исправлением стало еще 60 тысяч фунтов стерлингов, которые были функцией validate(), которая проверяла только наличие ключевых слов union, select, having и других.Когда меня спросили о том, что они сделали для канонизации / кодирования (что мне пришлось потом объяснять), это было время перекати-поля.

Дом разработчиков и (дорогой) проект были законсервированы.

Вы могли бы рассмотреть возможность проверки содержания

 v_start_name 
.Проверьте строку на наличие точек с запятой, символов комментариев, равенства и т.д.Не забудьте проверить наличие как символов, так и шестнадцатеричных значений.Не забудьте разрешить использование имени через дефис, например"Смит-Браун", вероятно, приемлем, "Смит-Браун" потенциально является инъекцией.

Если вы не знакомы с Hex в SQL-инъекции, ниже приведены краткие вводные

http://www.arejae.com/blog/sql-injection-attack-using-t-sql-and-hexadecimal.html

http://www.securityfocus.com/infocus/1768

DECLARE
      v_start_name ALIAS FOR $1;
      r_player  v_player%ROWTYPE;
      v_temp VARCHAR;
   BEGIN
      --  new pseudo code here
      if v_start_name has bad chars exit with error message
      -- end pseudo code here
      v_temp := v_start_name || ''%'';
      FOR r_player IN
         SELECT first_name, last_name FROM v_player WHERE last_name like v_temp
      LOOP
         RETURN NEXT r_player;
      END LOOP;
      RETURN;
   END;

С уважением Карл

Просто замените ваше имя v_start_name, чтобы избавиться от ";" и т.д.ie

v_clean_name VARCHAR;
Select v_clean_name = Replace(v_start_name,';','');

Это заменит ;с пробелами, препятствующими атаке SQL-инъекцией

Для получения более подробной информации смотрите Строковые функции в PostgresSQL

Как также прокомментировала LFSR Consulting.Лучше внести в белый список (т. е. Не обрабатывать какие-либо входные данные с недопустимыми символами, такими как ';'), а не в черный список (т. е. попытаться очистить данные, поскольку пользователь может выполнить атаку SQL-инъекцией и на вашу замену).

Для получения дополнительной информации взгляните на Атаки с использованием SQL -инъекций

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top