Возможно ли внедрение SQL с этим запросом? - PullRequest
0 голосов
/ 28 февраля 2011
UPDATE `company` SET `itnumber` = '595959' WHERE (id = 932) 

Таким образом, значение itnumber исходит из пользовательского ввода для этой компании.Я хочу убедиться, что я могу предотвратить любые инъекции SQL.Таким образом, пользователь вводит 595959, и я строю это значение как 595959 в динамическом запросе.Возможно ли в этом запросе использовать SQL-инъекцию?Мне известно об использовании оператора prepare для предотвращения внедрения SQL, но подготовка оператора может потребовать много усилий для разработки моего приложения, поэтому я ищу менее трудоемкий и более простой подход для исправления большинства моих операторов SQL, где внедрение возможно.

StringBuffer sb = new StringBuffer();
sb.append(" UPDATE ");
sb.append(DB.quote(table));
sb.append(" SET ");
/* logic if column value has changed */
/* if yes */
sb.append(DB.quote(column.name));
sb.append(" = ");
sb.append(column.getSQLvalue());
sb.append(" WHERE (id = ");
sb.append(columns[0].getSQLvalue());
sb.append(")");
execute(sb.toString());

Ответы [ 4 ]

8 голосов
/ 28 февраля 2011

Если вы просто объединяете входные данные в строку SQL без каких-либо очисток (и просто заключаете их в одинарные кавычки ' не делает его чистым), то да, это уязвимо для внедрения SQL.

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


Обновление:

Поскольку вы используете getSQLvalue() из библиотеки Oracle SQL, это будет гарантировать, что переданное значение будет экранировано правильно. Это действительно безопасно от SQL-инъекций, однако вам нужно помнить, чтобы использовать его везде. Однако использование параметров гарантирует то же самое, без риска забыть экранировать значения SQL.

3 голосов
/ 28 февраля 2011

Мне известно об использовании оператора подготовить использовать для предотвращения инъекции SQL, но подготовка заявления может занять много усилия по развитию для моего приложение, поэтому я ищу меньше трудоемкий и простой подход к исправить большинство моих SQL-операторов где возможна инъекция.

Вы будете удивлены, насколько меньше времени потребуется для реализации решения right с самого начала. Кроме того, почему это сложнее, чем объединение строки запроса?

PreparedStatement pstmt = con.prepareStatement(
       "UPDATE `company` SET `itnumber` = ? WHERE (id = ?)"
   );
pstmt.setString(1, "595959");
pstmt.setInt(2, 932);

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

3 голосов
/ 28 февраля 2011

Да, это так. Например:

UPDATE `company`
SET `itnumber` = '595959'; DROP TABLE company; --' WHERE (id = 932)

Возможно, сработает.

1 голос
/ 28 февраля 2011

На самом деле самое безопасное - создать для этого сохраненный процесс, тогда ваши типы данных хотя бы немного вас защитят.

CREATE PROC usp_Update_itnumber_by_Company_Id

@itnumber int
, @Company_Id int

as

BEGIN TRAN    
UPDATE [Company]
SET itnumber = @itnumber
WHERE id = @Company_Id;

COMMIT TRAN 

На этом пути, если если; Компания DROP TABLE; - 'WHERE (id = 932) передается в @Company_Id, он потерпит неудачу, так как тип данных является несовпадением.

Если вы пытаетесь определить, какие столбцы обновить, и только если они изменились, вы можете попробовать выполнить MERGE вместо UPDATE . Таким образом, вы можете получить текущее состояние записи и обновить его, только если они не совпадают.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...