首先,我知道这是不好的做法,但无论如何我仍在寻找答案。
在我们的 Web 应用程序中,我们有一个文本区域,用户可以在其中编写 SQL 来引入自定义数据集并在图表中查看它们。其工作方式本质上是获取写入的字符串并将其作为查询执行。我正在寻找的是我需要在应用程序服务器后端安全方面实现的一切,以禁止执行产生 SELECT
类型查询以外的结果的查询。
用户将无法执行他想要的任何类型的 SELECT
查询,因为应用服务器后端将返回的结果集扩展为包含 2 个名为 X_FIELD
的列,并且Y_FIELD
因此,我们并不担心用户能够查看数据,而是担心用户执行会破坏数据库的 SQL。
我们想做的是解析字符串中的关键字,例如 DROP
、ALTER
、CREATE
等。我们是否有具体的事情有什么要注意的吗?有没有一个工具/库可以自动执行此操作?我们使用 java 作为后端代码。
最佳答案
过滤查询可以在应用程序级别完成,但与为每个数据库创建单独的安全系统相比,它需要更多的数据库特定专业知识。
作为示例,我创建了一个 open source program可以为 Oracle 做到这一点。它不会解决您的问题,但代码至少可以帮助解释为什么这是一个坏主意。
首先,了解 Oracle SQL 语法比大多数编程语言(例如 Java)复杂得多,这一点很重要。 Oracle有2175个关键字,几乎没有一个是保留的。忘记解析 SQL - 现有的第 3 方解析器都不够准确,无法安全地执行此操作。
幸运的是,此任务不需要完整的解析器。 Oracle 语法的结构方式使得任何语句都可以仅用 8 个标记进行分类,不包括 空格和注释。
但是建立一个 tokenizer和一个
statement classifier还是很难。该解决方案将处理
不常见的选择类型,例如 (select * from Dual)
或 with asdf as (select 1 a from Dual) select a from asdf;
。但即使是 SELECT
语句也可能导致
对数据库的更改;通过隐藏在函数或类型中的 PL/SQL,或者通过更新
锁定行。
并且不要忘记删除(有时是可选的)terminator 。他们工作得很好
在大多数 IDE 中,但在动态 SQL 中不允许使用。不要只删除最后一个字符或最后一个标记,因为某些 SELECT
语句允许中间使用分号。
对于一个数据库而言,这就是一项艰巨的工作!如果您想使用此方法来实现安全策略,您需要几乎 100% 的准确性。很少有人对任何数据库有足够的狂热来构建这个。您不可能对多个数据库执行此操作。
关于java - 过滤应用程序服务器上执行的 SQL 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32588285/