Переменные имена столбцов с использованием подготовленных операторов - PullRequest
35 голосов
/ 29 июня 2010

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

Я использую 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.

Ответы [ 6 ]

33 голосов
/ 29 июня 2010

Это указывает на плохой дизайн БД.Пользователь не должен знать о названиях столбцов.Создайте реальный столбец БД, в котором хранятся эти «имена столбцов», и вместо этого сохраните в нем данные.

В любом случае, нет, вы не можете установить имена столбцов как значения PreparedStatement.Вы можете установить только столбцы значения как PreparedStatement значения

Если вы хотите продолжить в этом направлении, вам нужно санировать имена столбцов и самостоятельно объединять / создавать строку SQL.Заключите в кавычки имена отдельных столбцов и используйте String#replace(), чтобы экранировать ту же кавычку в имени столбца.

15 голосов
/ 26 апреля 2012

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

2 голосов
/ 29 июня 2010

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

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

0 голосов
/ 20 апреля 2017
public void MethodName(String strFieldName1, String strFieldName2, String strTableName)
{
//Code to connect with database
String strSQLQuery=String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
st=conn.createStatement();
rs=st.executeQuery(strSQLQuery);
//rest code
}
0 голосов
/ 19 апреля 2017

Ниже приведено решение в Java.

String strSelectString = String.format("select %s, %s from %s", strFieldName, strFieldName2, strTableName);
0 голосов
/ 03 февраля 2017

Используйте недостаток sql-инъекций в Statement Interface как преимущество. Пример:

st=conn.createStatement();
String columnName="name";
rs=st.executeQuery("select "+ columnName+" from ad_org ");
...