在我工作的公司,我们有一个支持工具,它提供了一个页面,允许用户运行SELECT查询。它应该防止用户运行UPDATE、INSERT、DELETE、DROP等。除此之外,每个select语句都被接受。
它的工作方式是通过执行
SELECT * FROM (<query>)
因此,除了SELECT之外的任何语句都应该由于语法错误而失败。
在我看来,这种方法不足以防止攻击,因为任何事情都可能更改out查询并破坏安全性。我确认,除了该解决方案之外,它还应该检查查询中的语法。我的同事要求我证明目前的解决方案是不安全的。
为了测试它,我试着写一些类似的东西
SELECT * from dual); DROP table users --
但由于SQL连接器不接受的字符。
那么,有什么方法可以在这样的查询中附加一个修改语句吗?
顺便说一下,它是Oracle SQL。
编辑:
更明确地说:我知道这不是一个好方法。但我必须向我的同事证明这一点,以证明修改代码的合理性。理论上的答案是好的,但我认为真正的注射会更有效率。
保护基于这样一种想法/假设,即"更新查询"永远不会生成结果表(这就是使其成为SELECT FROM(…(的有效子表达式所需的条件(。
带有专有语言扩展的专有引擎可能会破坏这种假设。尽管无可否认,这似乎仍然不太可能,但在专有扩展的世界里,确实有一些疯狂的东西在四处传播,所以不要想当然。
也许还要注意表达式编译器将"不返回表"强制为"某种空表"。你知道。因为任何系统都必须尽其所能让用户操作成功,而不是失败/崩溃/。。。
也许还可以考虑,如果"查询任何你喜欢的"真的是需要的函数,那么你的DBMS很可能已经有了一些工具或组件,实际上允许。。。(甚至是专门为此目的而设计的(。
我假设用户可以接受从该帐户访问的任何数据(因为这似乎是设计的目的(。
用这种方法执行拒绝服务也是相当琐碎的,要么是低效的查询,要么是用于锁定关键表的选择更新。
Oracle是一个功能丰富的数据库,这意味着可能有多种方法可以在查询中运行DML。您需要找到一个内联PL/SQL函数,该函数允许您执行DML或具有其他副作用。它将取决于具体的模式,以确定哪些包是可用的——XML DB包有一些运行任意SQL的机制,UTL_HTTP包通常可以用来发起网络攻击,java功能非常强大。
防止这种情况发生的正确方法是使用DB安全机制——针对只读模式(仅在表上具有查询权限的模式(运行此机制。