Нейтрализация опасного входа для предотвращения атак путем инъекций.

Эта статья является частью серии. Прочтите предыдущую статью здесь: https://medium.com/@paul_io/security-code-review-101-input-validation-f309b1be96c7

О инъекции

В предыдущей статье мы рассмотрели Проверка ввода. Хотя Проверка ввода является эффективным средством сдерживания большого количества атак, включая Внедрение, не весь ввод можно фильтровать.

Например, представьте, что кого-то зовут О’Брайен. Одиночная кавычка в О’Брайене также является частью синтаксиса команд SQL. Например, веб-сайт может выполнять поиск записей в базе данных следующим образом:

Обратите внимание, что одинарная кавычка в имени О’Брайен вызывает синтаксическую ошибку. Обработчик команд SQL считает, что строка заканчивается на O, а остальное, BRIEN%, - просто нераспознанная команда.

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

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

Давайте посмотрим на следующий фрагмент кода.

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

Нет никакой проверки ввода и никакого экранирования ввода. Это означает, что пользователь, вводящий О’Брайен, вызовет синтаксическую ошибку SQL, что является ошибкой. Однако злоумышленник может воспользоваться таким поведением. Что произойдет, если пользователь введет что-то вроде строки ниже?

SQL-запрос, передаваемый в базу данных, в конечном итоге будет двумя разными командами. Один выбирает всех пользователей в базе данных, а другой удаляет таблицу пользователей.

Если эти концепции новы для вас, теперь вы можете, наконец, насладиться этой старой хакерской шуткой о маленьких столиках Бобби.

Предотвращение инъекции

Как предполагает старый комикс, дезинфекция пользовательского ввода могла бы предотвратить проблему. «Санитарная обработка» могла быть произведена с помощью проверки ввода или экранирования одинарной кавычки. Однако не все вводимые данные могут быть проверены, и не все SQL-инъекции выполняются с использованием одинарных кавычек.

В приведенном ниже примере Injection использует незащищенный параметр ORDER BY:

В этом случае можно использовать Проверка ввода, поскольку имена столбцов должны быть буквенно-цифровыми, однако это приводит к более сложной стратегии защиты, когда приложение должно использовать Проверка ввода для значений, входящих в ORDER BY и Escaping для значений, входящих в предложение WHERE.

Однако есть более простой способ. Не используйте объединение вообще. Этот подход также верен для других сценариев внедрения, таких как внедрение команд.

Это сценарий, в котором мы можем использовать бритву Оккама, чтобы определить простейшую и универсальную защиту от атак инъекций. Решением здесь является использование параметризованных операторов.

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

В Java это может быть достигнуто с помощью Подготовленного оператора, как показано в примере ниже . Вопросительный знак в строке запроса в строке 3 является заполнителем для значения параметра.

При работе с командами ОС лучше полностью избегать их и писать эквивалентные функции на выбранном вами языке программирования. Например, если вы должны прочитать файл на Java, используйте такие API, как File и BufferedReader, а не команду Linux cat. Однако в некоторых случаях выбора нет, и код должен быть «Shell Out». Для таких ситуаций эквивалентом Подготовленного оператора является передача аргументов командной строки в виде отдельного массива, что позволяет избежать конкатенации.

Объектно-реляционное отображение (ORM)

Есть еще лучший способ абстрагировать операторы SQL от кода приложения. Фреймворки ORM позволяют разработчикам работать с объектами, а не с SQL-запросами. Вместо того, чтобы работать с таблицей users, разработчики будут работать с коллекцией пользователей и выполнять для этой коллекции метод, возвращающий соответствующую запись.

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

Осторожность

Бывают случаи, когда внедрение по-прежнему происходит, несмотря на использование параметризованных операторов. Например, когда инъекция происходит в хранимой процедуре базы данных или выполняется сценарий оболочки ОС.

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

Подводя итог всему этому

При рассмотрении изменения кода, которое затрагивает командный процессор, обратите внимание на следующее:

  • Проверка ввода для известных буквенно-цифровых значений
  • Использование параметризованных заявлений
  • Используя структуру ORM, если применимо

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

Щелкните следующую ссылку, чтобы перейти к следующей статье из серии: https://medium.com/@paul_io/security-code-review-101-memory-adf0543926ee

Полный обзор кода безопасности серии 101