【问题标题】:Filtering executed SQL queries on application server过滤应用服务器上执行的 SQL 查询
【发布时间】:2015-09-15 14:09:32
【问题描述】:

首先,我知道这是不好的做法,但无论如何我仍在寻找答案。

在我们的 Web 应用程序中,我们有一个文本区域,用户可以在其中编写 SQL 以引入自定义数据集并在图表中查看它们。它的工作方式本质上是获取写入的字符串并将其作为查询执行。我正在寻找的是我需要在我们的应用服务器后端安全方面实现的一切,以禁止执行产生除SELECT 类型查询以外的结果的查询。

用户将无法执行他想要的任何类型的 SELECT 查询,因为应用服务器后端将返回的结果集扩展为具有名为 X_FIELDY_FIELD 的 2 列,所以我们不是那么多担心用户查看数据的次数与执行会破坏数据库的 SQL 一样多。

我们的想法是解析字符串中的关键字,例如DROPALTERCREATE 等。有什么需要特别注意的吗?是否有自动化的工具/库?我们使用 java 作为后端代码。

【问题讨论】:

  • 如何创建对数据库的访问权限非常有限的用户?
  • 你知道它运行的是 SQL Server 还是 Oracle?
  • @jarlh 正如它在标签中所说,应用程序可以在两台服务器上运行(甚至更多,但标签不适合)所以这必须涵盖它们。
  • 感谢您的澄清! (通常不涉及的产品被标记...)
  • 我们在现成的应用程序中有类似的功能。一位用户从 a_very_large_table 中选择 * 并为其他所有人冻结了数据库,而这需要数小时才能完成。当我们终止会话时,它会使应用服务器崩溃。我们不再允许这样做......

标签: java sql sql-server oracle sql-injection


【解决方案1】:

过滤查询可以在应用程序级别完成,但与为每个数据库创建单独的安全系统相比,它需要更多特定于数据库的专业知识。

例如,我创建了一个open source program 可以为 Oracle 执行此操作。它不会解决您的问题,但代码至少可以帮助解释为什么这是一个坏主意。

首先,重要的是要了解 Oracle SQL 语法比大多数编程语言(例如 Java)复杂得多。 Oracle 有 2175 个关键字,几乎没有一个是保留的。忘记解析 SQL - 现有的第 3 方解析器都不够准确,无法安全地执行此操作。

幸运的是,此任务不需要完整的解析器。 Oracle 语法的结构使得任何语句只能用 8 个标记进行分类,不包括 空格和 cmets。

但是构建一个 tokenizer 和一个 statement classifier 仍然很难。该解决方案将处理 不寻常的选择类型,例如(select * from dual)with asdf as (select 1 a from dual) select a from asdf;。但即使是SELECT 语句也可能导致 更改数据库;通过隐藏在函数或类型中的 PL/SQL,或者通过 for update 锁定行。

不要忘记删除(有时是可选的)terminator。他们工作正常 在大多数 IDE 中,但它们在动态 SQL 中是不允许的。不要只删除最后一个字符或最后一个标记,因为某些SELECT 语句允许在中间使用分号。


这对于一个数据库来说是很多工作!如果您想使用这种方法来实施安全策略,您需要几乎 100% 的准确性。很少有人对 any 数据库有足够的狂热来构建它。您不可能对多个数据库执行此操作。

【讨论】:

  • 谢谢。我会告诉你正确的做法是不要实现它,并且没有办法让它安全。
猜你喜欢
  • 1970-01-01
  • 2020-02-12
  • 1970-01-01
  • 1970-01-01
  • 2010-11-13
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多