Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
尝试在使用JPA动态引用Oracle包时阻止SQL注入_Oracle_Jpa - Fatal编程技术网

尝试在使用JPA动态引用Oracle包时阻止SQL注入

尝试在使用JPA动态引用Oracle包时阻止SQL注入,oracle,jpa,Oracle,Jpa,我走了一段路,遇到了一堵墙,想知道如何才能做到这一点 基本上,查询是使用JPA构造的,并传递给Oracle数据库。数据库上有一个包,用于生成引用,该包根据环境动态命名。此值可由用户编辑,并作为DB属性存储在应用程序中。我无法控制这个系统的架构 在JPA之前的阶段,使用包的引用值生成一个查询字符串,该值被设置为属性(同样,我不能改变它的设计方式)。我使用Query方法setParameter()设置了此项,如下所示: (伪代码替换聚焦上下文的不相关部分) 我这样做基本上是一种反射,只是意识到(在r

我走了一段路,遇到了一堵墙,想知道如何才能做到这一点

基本上,查询是使用JPA构造的,并传递给Oracle数据库。数据库上有一个包,用于生成引用,该包根据环境动态命名。此值可由用户编辑,并作为DB属性存储在应用程序中。我无法控制这个系统的架构

在JPA之前的阶段,使用包的引用值生成一个查询字符串,该值被设置为属性(同样,我不能改变它的设计方式)。我使用
Query
方法
setParameter()
设置了此项,如下所示:

(伪代码替换聚焦上下文的不相关部分)

我这样做基本上是一种反射,只是意识到(在retrospec中,很明显)这实际上不起作用,因为它正在逃逸不应该逃逸的元素

因此,当
引用f=“DynamicallyNamedPackage.DoThisDynamicallyNamedThing”
时,上面的代码只会返回
“DynamicallyNamedPackage.DoThisDynamicallyNamedThing”
,因为这显然是为了使其安全,这样做的目的在某种程度上是我尝试做的前提

有没有可能在不创建一整段额外代码的情况下实现这一点?作为替代方案,我目前所能想到的是查询匹配的所有包对象的
dba_过程
,并使用该查询的结果来构造
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注入”作为不允许使用非预期值在设计之外操纵DB的定义。)

Oracle dictionary视图包含当前用户可访问的所有过程的列表

特别是在视图中,有列
所有者、对象名称(=包名称)、过程名称

您可以使用此视图通过简单地添加
EXISTS
子查询来清理配置的输入,例如:

select 
 ?
from dual where exists (
  select null from all_procedures
  where 
   OWNER||'.'||OBJECT_NAME||'.'||PROCEDURE_NAME = upper(?) and
  object_type = 'PACKAGE');
必须绑定两次相同的输入参数

如果没有具有给定名称的过程,查询将返回
无数据
,因此您可能会引发异常


上面的查询需要一个完全限定的存储过程名称,即
owner.package.procedure
,如果允许使用非限定名称(没有
owner
),则必须稍微调整它。

您不想在这里阻止SQL注入。你想做SQL注入,不是吗?如果选择了这种设计,我想用户可以从dual中选择并存储要选择的对象的名称,并且用户或值已经过验证。所以就这样吧。我想答案是肯定的,这是基于SQL注入的概念,但“SQL注入”的概念并不是指未经授权/无意地劫持允许注入SQL(而不是引用对象)的查询。设计是一个问题,但不是我能控制的问题。谢谢-嵌套的
EXISTS
语句对单个
SELECT过程名有好处吗,其中PRODECURE\u NAME=?
,除了style?@ChrisJ之外,视图
all\u过程
可以为一个过程包含多行(每过载一个)。使用
EXISTS
返回最大一行。使用
SELECT DISTINCT
也可以实现同样的效果。啊,好吧-我的描述可能过于简洁,但这可能会扩展为针对包内的特定函数,此时应该只有一行返回?一般情况下,打包的procedure可能有多个重载(即相同的过程名称,但不同的参数),因此您可以为单个
所有者.PACKAGE\u name.procedure\u name
获取更多行。这很有意义-我使用了一个修订版本,但查询非常有用;谢谢!
select 
 ?
from dual where exists (
  select null from all_procedures
  where 
   OWNER||'.'||OBJECT_NAME||'.'||PROCEDURE_NAME = upper(?) and
  object_type = 'PACKAGE');