SQL-инъекция - как очистить созданное программой предложение sql?

в стандартном Ajax, , где и упорядочены по предложениям SQL предоставляются программа (не пользователь), например

var url = ".select?dd=emp&where="+escape("emp_tp='abc' and hire_dt<current_date-'2 years' and super_emp_id is distinct from emp_id")

ответила на сервере

$where = (isset($_GET['where'])) ? pureClause($_GET['where']) : null;
$order = (isset($_GET['order'])) ? pureClause($_GET['order']) : null;
...
$query = $query.(($where)?" where $where":'').(($order)?" order by $order":'');

, вопрос в том, как должна выглядеть функция pureClause ?

прямо сейчас pureClause просто вызывает ошибку если существует что-либо из следующего:

; select insert update delete drop create truncate

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

мне это кажется адекватным, но в глубине души я знаю, что ' m неверно.

Уточнения:

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

Наконец, рассмотрите предложение where

emp_tp='abc' and hire_dt=current_dt-'2 years' and super_emp_id is distinct from emp_id

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


Основные факты:

  • не практично писать синтаксический анализатор предложения SQL для параметризованных подготовленных операторов
  • не практично писать дезинфицирующее средство предложения SQL, которое гарантирует отсутствие вреда

Решение:

для SELECTS, где случайный SQL может быть проблемой: поскольку слишком сложно защитить базу данных, позвольте базе данных защитить себя! у разных пользователей разные роли / разрешения. использовать для выбора пользователя с правами только для чтения. для обычного SQL это гарантирует отсутствие DML из этих операторов.

передовой опыт: четыре пользователя базы данных имеют доступ к

  1. разработчику , делают все ( никогда не используются в качестве соединения в веб-приложении)
  2. dml - может select / dml почти для всего (необходимо использовать для dml)
  3. читать - можно выбрать (использовать для всех выборок, подготовленных или текстовых)
  4. login - может выполнять только функции входа / пароля (используется в процессе входа в систему)

защита паролем:

  • dml и чтение могут не иметь доступа к данным пароля, либо через select, либо через dml
  • логин должен получить доступ к данным пароля только через защищенные функции, например,
     function login( username, password ) - returns user_id
     function set_password( usr_id, password ) - sets password
  • только логин может запускать функции login () и set_password ()
  • в зависимости от вашего база данных, логин может потребовать доступ sql к столбцам паролей
  • в зависимости от вашей базы данных, столбец пароль может быть защищен сам; если нет, то его следует переместить из таблицы user в его собственную защищенную таблицу

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

6
задан cc young 6 September 2011 в 04:48
поделиться