[closed] Валидация ввода пользователя для предотвращения SQL-инъекций

Oper

Интересуют алгоритмы, а также готовые решения для надежной валидации вводимых пользователем данных в шаблонах запросов вида

SELECT * FROM table WHERE field = %s;

Хотелось бы что-то в духе parse tree validation...
Предпочтительный язык - Python.
Спасибо.

milanadiana

может так:
SELECT * FROM table WHERE field = '%s';

Объясните мне, что нужно, кроме фильтра на одинарные кавычки.

Alexander08

гугл

Alexander08

гугл!да, гугл

Gaishnik

Я не знаю, как в питоне, а в Java стандартная библиотека не содержит функции, которая преобразует строку для подстановки в запрос. Вместо этого предполагается, что ты пользуешься интерфейсом PreparedStatement, который позволяет сначала передать СУБД сам запрос, а потом забиндить значения переменных. Такой способ теоретически является более правильным с точки зрения перформанса, так как например Oracle сможет повторно использовать распарсенные запросы.
В питоне наверное дела обстоят также.

Oper

Строка может содержать одинарные кавычки

Oper

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

milanadiana

О! Спасибо, что сказал, возьму на заметку. А то я обычно либо так пихал, либо делал обычный Statement и потом пихал через ResultSet.

Gaishnik

Если ты пользуешься этим интерфейсом, то строка не проходит через СУБДшный парсер запросов, поэтому все равно содержит она кавычки или нет.

Oper

Я примерно представляю, о чем ты говоришь, примерно так у меня и сделано в 99% запросов. Но тут особый случай, для него пришлось непосредственно писать SQL запрос.

Syraya

Тогда ОК!
Если особый случай, то, наверное, можно оставить его открытым для инъекций!

conv3rsje

Интересуют алгоритмы
http://blog.moertel.com/articles/2006/10/18/a-type-based-sol...
труъ шняга, правда, для типизованных языков :(

doublemother

Проэкранируй все одинарные кавычки. Будет тебе счастье.

zya369

они вроде не экранируются, а на '' (две одинарных кавычки) заменяются

vall

нахрена? встроенные средства dbapi прекрасно всё реализуют без дырявых велосипедов в духе пхп

Corrector

В SQLIte вроде бы нужно экранировать только одинарные кавычки. Вот так, например (код для дельфи)
 
SQLText := Format('SELECT * FROM table WHERE field = "%s"', [
StringReplace(UserFieldValue, '''', '''''', [rfReplaceAll])]);

rosali

> Такой способ теоретически является более правильным
в теории всё так, но в жизни бывает, что от пользовательских данных зависит например имя таблицы, в которую задается запрос или какие поля выбираются. так что ничего не поделаешь, приходится строить запрос на лету, и нужна функция, которая будет проверять вводимые данные на инъекции. и вряд ли такая функция будет в стандартной библиотеке, потому что способ проверки необычный, например

$table =~ /`/ and die;
$dbh->do("insert `$table` ...");

katrin2201

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

rosali

> имена колонок надо брать не из юзеринпута, а из своих внутренних мапов
а потом когда в таблице добавляется колонка, надо идти искать разработчика, чтобы он её в этот свой внутренний мап добавил, пересобрал программу, поставил в тестинг, подождал денек, потом выкатил, в чем смысл :-\ неужели так сложно написать проверку, что имя колонки состоит только из букв цифр и подчерка...
зато теоретически всё правильно!

SCIF32

а потом когда в таблице добавляется колонка
а что - колонки свтой дух что-ли добавляет?
если меняется БД, то вполне логично, что разработчик должен потом поучаствовать.
или инженер БД будет отвечать за появившиеся баги?

Dasar

неужели так сложно написать проверку, что имя колонки состоит только из букв цифр и подчерка...
приведи, пожалуйста, реальный use case, когда имя колонки или таблицы вводится пользователем
ps
чтобы выбирался я еще могу придумать, но тогда как раз на сервере строится map, а пользователю передаются какие-то идентификаторы из map-а, а не реальные имена колонок/таблиц.

milanadiana

Да "вводится" - это черезчур)

psihodog

приведи, пожалуйста, реальный use case, когда имя колонки или таблицы вводится пользователем
когда ты хочешь оставить пользователю возможность вводить запросы руками, а ограничивать его встроенным генератором

katrin2201

Так а смысл защищаться тогда от sql-инъекций, если ты пользователю и так позволяешь из произвольной таблицы заселектить произвольную колонку?
Не хочется искать программиста - открываешь БД на чтение\запись всем, и вперед...
Оставить комментарий
Имя или ник:
Комментарий: