Имена столбцов переменных с использованием подготовленных инструкций
Мне было интересно, есть ли какой-либо способ указать возвращаемые имена столбцов с помощью подготовленных инструкций.
Я использую MySQL и Java.
Когда я попробую это:
String columnNames="d,e,f"; //Actually from the user... String name = "some_table"; //From user... String query = "SELECT a,b,c,? FROM " + name + " WHERE d=?";//... stmt = conn.prepareStatement(query); stmt.setString(1, columnNames); stmt.setString(2, "x");
Я получаю этот тип инструкции (печать непосредственно перед выполнением).
SELECT a,b,c,'d,e,f'FROM some_table WHERE d='x'
Однако я хотел бы видеть:
SELECT a,b,c,d,e,f FROM some_table WHERE d='x'
Я знаю, что не могу сделать это для имен таблиц, как обсуждалось здесь, но мне было интересно, есть ли какой-нибудь способ сделать это для имен столбцов.
Если нет, то мне просто нужно попробовать и убедиться, что я очищаю входные данные, чтобы это не привело к уязвимостям SQL-инъекций.
Переведено автоматически
Ответ 1
Это указывает на плохой дизайн базы данных. Пользователю не нужно знать об именах столбцов. Создайте реальный столбец базы данных, который содержит эти "имена столбцов", и вместо этого сохраните данные вдоль него.
И в любом случае, нет, вы не можете задавать имена столбцов в качестве PreparedStatement значений. Вы можете задавать только значения столбцов в качестве PreparedStatement значений
Если вы хотите продолжить в этом направлении, вам необходимо очистить имена столбцов (чтобы избежать SQL-инъекции) и объединить / создать SQL-строку самостоятельно. Заключите в кавычки отдельные имена столбцов и используйте String#replace() для экранирования той же кавычки внутри имени столбца.
Ответ 2
Подготовьте белый список разрешенных имен столбцов. Используйте "запрос", чтобы посмотреть, есть ли в белом списке имя столбца. Если нет, отклоните запрос.
Ответ 3
Для подготовленных инструкций MySQL с NodeJS (mysqljs / mysql) вам нужно знать, что ? это для значений, но если вам нужно экранировать имена столбцов, таблицы и т.д., используйте ?? вместо этого.
Что-то вроде этого будет работать:
SELECT??, ??, ??FROM??WHERE?? < ?
Установите значения в ['id', 'name', 'address', 'user', 'id', 100]
Ответ 4
Я думаю, что этот случай не может сработать, потому что весь смысл подготовленной инструкции заключается в том, чтобы запретить пользователю вводить неэкранированные биты запроса - так что у вас всегда будет текст, заключенный в кавычки или экранированный.
Вам необходимо очистить этот ввод в Java, если вы хотите безопасно повлиять на структуру запроса.