Я прошел немного по дорожке и ударил стену о том, как этого можно достичь.
По сути, запрос строится с использованием JPA и передается в БД Oracle.На БД есть Пакет, используемый для генерации ссылки, который имеет динамическое имя в зависимости от среды.Это значение доступно для редактирования пользователем и хранится как свойство БД в приложении.У меня нет никакого контроля над архитектурой этого.
На этапе до JPA строка запроса генерируется с использованием ссылочного значения для пакета, который устанавливается как свойство (опять же, я могуне изменить способ, которым это было разработано).Я настроил это, используя Query
метод setParameter()
, например так:
(псевдокод, заменяющий несущественные части для сфокусированного контекста)
String referenceRef = [ reference is fetched from DB properties ];
String queryString = "SELECT ?1 FROM sys.dual";
final Query myQuery = getEntityManager().createNativeQuery( queryString );
myQuery.setParameter( 1, referenceRef );
return myQuery.getSingleResult();
Я довольномногие делали это как рефлекс, только чтобы понять (в ретроспективе, совершенно очевидно), что это на самом деле не сработает, так как это экранирование от элемента, который не должен быть экранирован ...
Итак, где referenceRef = "DynamicallyNamedPackage.DoThisDynamicallyNamedThing"
, приведенный выше код просто вернет "DynamicallyNamedPackage.DoThisDynamicallyNamedThing"
, поскольку это, очевидно, делает его безопасным, и смысл этого в некоторой степени заключается в том, что я пытаюсь сделать то же самое.
Возможно ли достичь этого без создания целого куска дополнительного кода?Все, что я в настоящее время могу думать, как альтернатива, это запросить dba_procedures
для всех объектов пакета, которые соответствуют, и использовать результат этого запроса для построения queryString
(следовательно, обходить круг с использованием любых редактируемых пользователем значений), но этотакое чувство, что оно будет запутанным.Это альтернатива, которую я использую вместо улучшения:
final String verifyReference = "SELECT object_name FROM "
+ "dba_procedures WHERE object_type = 'PACKAGE' AND object_name =?1";
final Query refQuery = getEntityManager().createNativeQuery( verifyReference );
refQuery.setParameter( 1, referenceRef );
final String result = refQuery.getSingleResult();
final String queryString = "SELECT " + result + " FROM sys.dual";
final Query myQuery = getEntityManager().createNativeQuery( queryString );
return myQuery.getSingleResult();
По сути, он ищет ссылку на редактируемое пользователем свойство в списке существующих пакетов, а затем использует результат этого запроса дляпостроение оригинальной ссылки.Он включает в себя больше нулевой проверки и т. Д. И устраняет уязвимость, но чувствует себя немного «неполированным».
(Как уже упоминалось в комментариях, этот вид предназначен дляSQL-инъекция, но она должна предотвращать «SQL-инъекцию» как определение, не позволяющее манипулировать БД вне проекта с использованием непреднамеренного значения.)