SQL инъекции

Статья основана на двадцать втором видео из 31 темы курса SQL 2.0 — PL/pgSQL в PostgreSQL от Аристова Евгения, который является логическим продолжением курса SQL c 0. Ссылки на видео на платформах RUTUBE и VK video.

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

В прошлой статье разбираются использование параметра search_path, ключевые моменты и рекомендации.

Презентация и исходники доступны по ссылке.

SQL injection

SQL инъекции в PostgreSQL — это уязвимости безопасности, возникающие при некорректной обработке пользовательского ввода, позволяющие злоумышленнику выполнить произвольный SQL-код.

-- УЯЗВИМЫЙ КОД
CREATE OR REPLACE FUNCTION vulnerable_login(username TEXT, password TEXT)
RETURNS BOOLEAN AS $$
DECLARE
  query TEXT;
  result BOOLEAN;
BEGIN
  query := 'SELECT EXISTS(SELECT 1 FROM users WHERE username = ''' ||
    username || ''' AND password = ''' || password || ''')';
  EXECUTE query INTO result;
  RETURN result;
END;
$$ LANGUAGE plpgsql;

-- АТАКА
SELECT vulnerable_login('admin', 'anything'' OR ''1''=''1');
-- Сгенерированный запрос, строка будет сконкатенирована:
-- SELECT EXISTS(SELECT 1 FROM users WHERE username = 'admin' AND password = 'anything' OR '1'='1')

Защита:

  • Использование параметризованных запросов
  • Использование форматирования с экранированием
  • Валидация входных данных
  • Использование защищенных процедур с нужными правами и отзыв прямого доступа

Основные ошибки:

-- Конкатенация строк для запросов
query := 'SELECT ... WHERE name = ''' || user_input || '''';

-- Динамический SQL без экранирования
EXECUTE 'SELECT ... WHERE name = ''' || user_input || '''';

-- Прямое использование пользовательского ввода
EXECUTE user_input;

Более подробно правильные варианты использования рассмотрим на следующей теме — динамический SQL.

Итоги

Ключевые принципы защиты:

  1. Всегда используйте параметризованные запросы
  2. Валидируйте и сканируйте все пользовательские данные
  3. Принцип минимальных привилегий для пользователей БД
  4. Экранируйте идентификаторы с помощью format() и %I
  5. Логируйте подозрительную активность
  6. Регулярно тестируйте на уязвимости

Больше примеров доступно на гитхабе и в видео.

В следующей статье мы разберём динамический SQL.


Опубликовано

в

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

7 + четыре =