我正在创建一个允许用户构造复杂SELECT语句的应用程序。生成的SQL不可信,并且完全是任意的。
我需要一种相对安全的方法来执行不受信任的SQL。我的计划是创建一个只对相关模式和表具有SELECT权限的数据库用户。不受信任的SQL将以该用户身份执行。
可能出现什么问题? :)
如果我们假设postgres本身没有严重的漏洞,那么用户可以进行一堆交叉连接并使数据库过载。这可以通过会话超时来缓解。
我觉得有很多事情可能会出错,但我在列出清单方面遇到了麻烦。
编辑:
根据目前为止的评论/答案,我应该注意到,在任何给定时间使用此工具的人数将非常接近0。
答案 0 :(得分:3)
SELECT查询无法更改数据库中的任何内容。缺少dba权限可确保无法更改任何全局设置。因此,超载确实是唯一的问题。
Onerload可能是复杂查询或过多简单查询的结果。
通过在statement_timeout
postgresql.conf
,可以排除过于复杂的查询
也可以避免收到简单查询的内容。首先,您可以为每个用户设置并行连接限制(alter user
和CONNECTION LIMIT
)。如果你在用户和postgresql之间有一些接口程序,你可以另外(1)在每次查询完成后添加一些额外的等待,(2)引入CAPTCHA以避免自动DOS攻击
ADDITION: PostgreSQL公共系统函数提供了许多可能的攻击向量。可以像select pg_advisory_lock(1)
一样调用它们,每个用户都有权调用它们。因此,您应该限制对它们的访问。好的选择是创建所有“可调用单词”的白名单,或者更准确地说,是可以在(
之后使用的标识符。并排除所有包含类似调用的构造identifier (
的查询,其标识符不在白名单中。
答案 1 :(得分:1)
想到的事情,除了让用户只使用SELECT并撤消对函数的权限外:
只读交易。当事务由BEGIN READ ONLY
或SET TRANSACTION READ ONLY
作为其第一条指令启动时,它无法写入任何内容,与用户权限无关。
在客户端,如果要将其限制为一个SELECT
,最好使用不接受捆绑到一个查询中的多个查询的SQL提交函数。例如,PQexec
API的swiss-knife libpq
方法确实接受了这样的查询,并且构建在它之上的每个驱动程序函数也是如此,例如PHP的pg_query
。
http://sqlfiddle.com/是一项专门用于运行任意SQL语句的服务,可以在某种程度上被视为一种概念验证,它可以在不被黑客攻击或DDos整天的情况下实现。
答案 2 :(得分:0)
这个问题,我不确定sql本身是否会在会话超时后仍然继续在后台运行(无论是通过谷歌还是没有任何实际经验都无法找到太多证据我自己也尝试过的地方)。如果你只是限制选择访问,我认为这是可能发生的最坏情况。真正的问题是如果你有一百个用户尝试进行复杂的交叉连接会发生什么?会话超时是否会丢弃查询,它会给数据库带来很大的负担(非常容易将数据库完全拉下来)
答案 3 :(得分:0)
在主服务器上使用精心设计的查询保护自己免受DoS攻击的唯一方法是在此副本数据库上设置Postgres数据库的只读副本和特殊的受限用户。这样主Postgres服务器就不会受到副本查询的影响。
当主DB由于某种原因失败时,你也会得到热备用/连续复制DB。