【问题标题】:Executing untrusted SQL with SELECT only user仅使用 SELECT 用户执行不受信任的 SQL
【发布时间】:2013-08-30 15:57:42
【问题描述】:

我正在创建一个允许用户构建复杂 SELECT 语句的应用程序。生成的 SQL 是不可信的,完全是任意的。

我需要一种方法来相对安全地执行不受信任的 SQL。我的计划是创建一个仅对相关架构和表具有 SELECT 权限的数据库用户。不受信任的 SQL 将以该用户身份执行。

这有什么可能出错? :)

如果我们假设 postgres 本身没有严重漏洞,那么用户可能会执行大量交叉连接并导致数据库过载。这可以通过会话超时来缓解。

我觉得还有很多事情不会出错,但我无法列出清单。

编辑:

根据迄今为止的 cmets/answers,我应该注意到在任何给定时间使用此工具的人数将非常接近 0。

【问题讨论】:

  • 将 SQL 和用户名发送到存储过程,并在事务中设置回滚?
  • PostGres 似乎没有能力限制特定查询使用的资源。如果这是正确的,那么对于这种类型的应用程序来说这是一个糟糕的选择:wiki.postgresql.org/wiki/Priorities PostgreSQL 无法限制特定用户、查询或数据库消耗的资源,
  • 您可以为不受信任的查询设置只读副本。这样他们就不会以任何方式影响主服务器。

标签: sql security postgresql user-input privileges


【解决方案1】:

SELECT 查询不能更改数据库中的任何内容。缺少 dba 权限保证无法更改任何全局设置。所以,过载确实是唯一的问题。

Onerload 可能是复杂查询或过多简单查询的结果。

  • 可以通过在postgresql.conf中设置statement_timeout来排除过于复杂的查询

  • 也可以避免接收大量简单的查询。首先,您可以为每个用户设置并行连接限制(alter user 和CONNECTION LIMIT)。如果你在用户和 postgresql 之间有一些接口程序,你可以额外(1)在每次查询完成后添加一些额外的等待,(2)引入 CAPTCHA 以避免自动 DOS 攻击

补充: PostgreSQL 公共系统函数提供了许多可能的攻击媒介。它们可以像select pg_advisory_lock(1) 一样被调用,并且每个用户都有权调用它们。因此,您应该限制对它们的访问。不错的选择是创建所有“可调用词”的白名单,或者更准确地说,是可以在它们之后与 ( 一起使用的标识符。并排除所有包含类似调用的构造 identifier ( 且标识符不在白名单中的查询。

【讨论】:

  • 在 postgres SELECT 查询可以改变任何东西。 SELECT destroy_database_function();
  • 不知道 statement_timeout,好主意。为此+1。我觉得 CAPTCHA 有点烦人,但也许它的其他一些变体,例如简单的拖放任务或启动查询的东西也可以工作。
  • 对于SELECT destroy_database_function(),您需要这样的功能和对其的执行权限。而且根据问题的陈述,您对某些表只有 SELECT 权限:) 我相信普通表上的 SELECT 权限远远不足以破坏某些东西。
  • 已经有像pg_advisory_lock()这样的函数可以用来对服务器进行DoS。并且它们可以通过public 获得,因此您必须了解所有 种可能的 DoS 案例以保护它们。我看到的唯一解决方案 - 为此类查询设置专用数据库副本
  • 是的,像pg_advisory_lock() 这样的公共系统功能是问题所在,感谢 Igor。但是,您必须知道所有可能的攻击向量才能阻止它们是不正确的——您可以创建函数白名单并排除所有查询,包括对其他函数的调用。专用数据库副本不是解决方案 - 它本身会受到 DoS 攻击,使我们的“查询工作台”不稳定。
【解决方案2】:

除了让用户只选择 SELECT 和撤销函数的权限之外,想到的事情:

  • 只读事务。当事务以BEGIN READ ONLY 或SET TRANSACTION READ ONLY 作为其第一条指令启动时,它不能写入任何内容,与用户权限无关。

  • 在客户端,如果要限制为一个SELECT,最好使用不接受多个查询捆绑为一个的SQL提交功能。例如,libpq API 的 swiss-knife PQexec 方法确实接受这样的查询,构建在它之上的每个驱动程序函数也是如此,例如 PHP 的 pg_query。

  • http://sqlfiddle.com/ 是一项专门用于运行任意 SQL 语句的服务,这可能被视为一种概念证明,它可以在不被黑客攻击或整天受到 DDos 攻击的情况下实现。

    李>

【讨论】:

    【解决方案3】:

    问题在于,我不确定 sql 本身在会话超时后是否仍会继续在后台运行(通过谷歌无法真正找到太多证据,也没有任何实际经验我自己也尝试过)。如果您仅限于选择访问权限,我认为这是可能发生的最坏情况。真正的问题是如果有一百个用户尝试进行复杂的交叉连接会发生什么?会话超时是否删除查询,它会给数据库带来真正的沉重负载(很容易足以完全关闭数据库)

    【讨论】:

      【解决方案4】:

      在主服务器上使用精心设计的查询来保护自己免受 DoS 攻击的唯一方法(从我的角度来看)是设置 Postgres 数据库的只读副本,并在此副本数据库上设置一个特殊的受限用户。这样主 Postgres 服务器就不会受到副本查询的影响。

      当主数据库由于某种原因发生故障时,您还将获得热备用/连续复制数据库。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-11
        • 1970-01-01
        • 2011-08-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多