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