Создание базы данных из пользовательского ввода с подготовленным оператором для предотвращения внедрения SQL - PullRequest
3 голосов
/ 10 мая 2019

В нашем приложении мы принимаем пользовательский ввод (например, имя проекта), а затем используем его для создания базы данных для пользователя (среди прочего). Я хотел бы предотвратить внедрение SQL, но не могу подготовить оператор SQL для создания базы данных и предоставления доступа. Есть ли безопасный способ запретить пользователям вводить SQL? Все, что я мог подумать, это ограничить ввод буквами английского алфавита и пробелами (а для имени БД заменить их символами подчеркивания), что, в свою очередь, могло бы обеспечить защиту, если мы заключим наши операторы SQL в одинарные кавычки. Это правдоподобное решение?

Мы используем загрузку java 8 / spring с базой данных Postgres 10.6. Я поиграл с SQL, и подготовленное заявление, насколько я понимаю, может использоваться только для запросов, таких как обновление, удаление и обновление. Я попытался поиграться с кодом, чтобы удалить некоторые таблицы из пользовательского ввода, но, к счастью, это не сработало, но я хотел бы быть уверен, что приложение не осталось уязвимым.

String createDbSQL = "create database ?";
Connection connection = DriverManager.getConnection(env.getDbUrl(), env.getDbUsername(), env.getDbPassword());
connection.setAutoCommit(false);
PreparedStatement preparedStatement = connection.prepareStatement(createDbSQL);
preparedStatement.setString(1, "test_db_name");
preparedStatement.execute();

завершается с org.postgresql.util.PSQLException: ERROR: syntax error at or near "$1" (что имеет смысл, если подготовленный оператор не может быть использован для создания базы данных`

PREPARE foo (text) AS create alter database $1;

ожидает выражения запроса и не работает

Ответы [ 3 ]

2 голосов
/ 11 мая 2019

В этом нет необходимости, и это может вызвать проблемы, выходящие за рамки возможностей внедрения SQL. Если вы отвечаете за предоставление базы данных, вы должны отвечать за присвоение имен.

Вы можете позволить пользователю указать имя, если это касается имени базы данных, но ваш код для создания и использования базы данных может использовать имя, которое вы сами генерируете и контролируете. Таким образом, если по какой-то причине вам нужно дать ему другое имя, или создать новую копию базы данных, или переключиться на другую платформу базы данных, где предоставленное пользователем имя следует другим правилам (и, возможно, их выбранное имя недопустимо) , вам не мешают ничего из этого.

1 голос
/ 11 мая 2019

Либо вы разрешаете только a-zA-Z0-9, либо можете использовать escapeLiteral

0 голосов
/ 11 мая 2019

Вам не разрешено создавать базы данных в синтаксисе PREPARE:

statement
Any SELECT, INSERT, UPDATE, DELETE, or VALUES statement.

( Postgresql 10 документов ) (Кстати: сейчас 10,8. Или 11,3)

Таким образом, вам придется создать базу данных в обычном выражении.

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

...