在Oracle(PL / SQL)中执行动态SQL并确保安全性

时间:2009-12-11 22:38:37

标签: sql database oracle security

如果我有一个有效的SQL字符串;无论如何我可以在我的PL / SQL中执行它 - 但保证它只是一个SELECT语句...没有进行复杂的解析以确保它没有任何转义字符/嵌套命令或任何爵士乐?

编辑:

我真正想要完成的是一个通用的,内置于​​我的应用程序,查询工具。它具有友好的,特定于域的GUI,并允许非技术用户创建相当复杂的查询。该工具处理搜索的版本控制,在需要的地方添加内部连接,以及一些其他特定于应用程序的东西,您将找不到典型的SQL DEV类型工具。

应用程序成功创建SQL查询。问题是我还允许用户直接输入自己的SQL。我担心潜在的SQL注入类型问题。

我不确定这是不是合适的地方;但是,除了这个问题之外 - 如果有人能推荐一本能让我加快这种性质的甲骨文的好书 - 我会非常感激。

5 个答案:

答案 0 :(得分:6)

一种解决方案是GRANT您的用户只有SELECT权限,如果这是用户被授权的唯一权限。

请参阅“Oracle Database Security Guide: Introduction to Privileges

但是,我认为您的应用程序不一定是安全的,因为您将查询限制为SELECT。当您允许不安全地使用SELECT查询时,可能存在恶作剧的例子。


你澄清的问题:我已经研究过SQL注入并写了很多。我可以建议的一般规则是:永远不要将用户输入作为代码执行。这就是SQL注入的方式。

您可以设计特定于域的语言并将用户输入映射到SQL操作,但请确保有一个层将用户选择转换为数据库架构。如果通过引入映射层将用户输入与SQL代码分开,那么你应该没事。

另请参阅我对“How do I protect this function from sql injection”的回答。

答案 1 :(得分:3)

Oracle为公众提供了许多执行权限。因此,即使没有显式插入/更新/删除/执行权限的用户也可以做恶作剧。

说到恶作剧,即使使用SELECT,用户也可能会遇到麻烦。 “SELECT * FROM table FOR UPDATE of column”将锁定整个表。 SELECT ... FOR UPDATE只需要SELECT权限。

哑查询(例如笛卡尔联接)可以使数据库满足其需求(尽管资源管理器应该能够通过仅允许少于指定数量的IO或CPU的查询来阻止它们中的大多数。)

如何为他们提供要执行的已批准SQL的列表,以及为他们提名包含SQL的过程?

答案 2 :(得分:1)

在oracle中,您可以检查第一个单词是“select”还是“with”。这是由于PL / SQL的Ada遗产,它要求复合语句在开始/结束块中,因此通常的SQL注入技术只会导致语法错误。

当然,最好的答案是通过授予权限并尽可能避免直接评估未知输入来实现此目的。但有趣的是,begin / end语法消除了很多SQL注入攻击向量。

答案 3 :(得分:1)

如果您给用户一个文本区域,以便他们可以输入他们想要的任何内容,嘿,SQL注入就是您想要的。

我不会像这样开门,但如果我被迫这样做,那么我会针对用户想要做的事情制定解释计划。优化器将解析查询并将有关SQL语句的所有信息放在plan_table表中,然后您可以查询它以检查它是否真的是一个select操作,哪些表/索引来自哪个模式,如果where子句是你赞成的东西,如果有任何“坏”操作,如笛卡尔连接或全表扫描等。

答案 4 :(得分:1)

writing injection proof pl/sql上查看Oracle的论文。 DBMS_ASSERT内置程序包应该可以帮助您测试SQL的适当性。

即使进行了这些测试,我也非常不愿意为人们提供一个开放式文本窗口来构建他们的查询,尤其是在公共网络或大型组织中,而您不了解每个人。有很有创意的人只是在寻找这样的机会。