过滤在应用程序服务器上执行的 SQL 个查询
Filtering executed SQL queries on application server
首先,我知道这是不好的做法,但无论如何我仍在寻找答案。
在我们的网络应用程序中,我们有一个文本区域,用户可以在其中编写 SQL 以引入自定义数据集并在图表中查看它们。它的工作方式本质上是获取写入的字符串并将其作为查询执行。我正在寻找的是我需要在我们的应用程序服务器后端安全方面实现的一切,以禁止执行产生 SELECT
类型查询以外的结果的查询。
用户将无法执行他想要的任何类型的 SELECT
查询,因为应用程序服务器后端将返回的结果集扩展为具有名为 X_FIELD
和 [=14= 的 2 列] 所以我们不太担心用户能够查看数据,因为他执行 SQL 会破坏数据库。
我们想做的是解析字符串中的关键字,例如 DROP
、ALTER
、CREATE
等。是否有我们需要注意的特定事项?是否有 tool/library 可以自动执行此操作?我们使用 java 作为后端代码。
过滤查询可以在应用程序级别完成,但它需要比为每个数据库创建单独的安全系统更多的特定于数据库的专业知识。
例如,我创建了一个可以为 Oracle 执行此操作的 open source program。它不会解决您的问题,但代码至少可以帮助解释为什么这是个坏主意。
首先,了解 Oracle SQL 语法比大多数编程语言(例如 Java) 复杂得多 很重要。
Oracle 有 2175 个关键字,其中几乎 none 个是保留的。忘记解析 SQL - none 现有的第 3 方解析器足够准确,可以安全地执行此操作。
幸运的是,此任务不需要完整的解析器。 Oracle 语法的结构使得任何语句都可以仅使用 8 个标记进行分类,不包括
空格和注释。
但是构建一个 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% 的准确性。很少有人对 任何 数据库狂热到足以建立这个。您不可能对多个数据库执行此操作。
首先,我知道这是不好的做法,但无论如何我仍在寻找答案。
在我们的网络应用程序中,我们有一个文本区域,用户可以在其中编写 SQL 以引入自定义数据集并在图表中查看它们。它的工作方式本质上是获取写入的字符串并将其作为查询执行。我正在寻找的是我需要在我们的应用程序服务器后端安全方面实现的一切,以禁止执行产生 SELECT
类型查询以外的结果的查询。
用户将无法执行他想要的任何类型的 SELECT
查询,因为应用程序服务器后端将返回的结果集扩展为具有名为 X_FIELD
和 [=14= 的 2 列] 所以我们不太担心用户能够查看数据,因为他执行 SQL 会破坏数据库。
我们想做的是解析字符串中的关键字,例如 DROP
、ALTER
、CREATE
等。是否有我们需要注意的特定事项?是否有 tool/library 可以自动执行此操作?我们使用 java 作为后端代码。
过滤查询可以在应用程序级别完成,但它需要比为每个数据库创建单独的安全系统更多的特定于数据库的专业知识。
例如,我创建了一个可以为 Oracle 执行此操作的 open source program。它不会解决您的问题,但代码至少可以帮助解释为什么这是个坏主意。
首先,了解 Oracle SQL 语法比大多数编程语言(例如 Java) 复杂得多 很重要。 Oracle 有 2175 个关键字,其中几乎 none 个是保留的。忘记解析 SQL - none 现有的第 3 方解析器足够准确,可以安全地执行此操作。
幸运的是,此任务不需要完整的解析器。 Oracle 语法的结构使得任何语句都可以仅使用 8 个标记进行分类,不包括 空格和注释。
但是构建一个 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% 的准确性。很少有人对 任何 数据库狂热到足以建立这个。您不可能对多个数据库执行此操作。