严格控制PostgreSQL中的statement_timeout变量

时间:2011-03-01 17:40:19

标签: security postgresql cpu-usage

有人知道如何限制用户设置变量的能力吗?具体是statement_timeout?

无论我是否更改用户将此变量设置为一分钟,或者如果我在postgresql.conf文件中将其设置为一分钟,用户始终只需键入SET statement_timeount TO 0;完全禁用该会话的超时。

有人知道阻止这种情况的方法吗?我知道有些变量只能由超级用户更改,但我无法弄清楚是否有办法强迫这是一个受控变量。或者,有没有办法从他们的角色撤销SET?

在我的应用程序中,此变量用于限制随机用户(用户注册向公众开放)使用所有CPU时间和(近)无限查询的能力。如果他们可以禁用它,那么这意味着我必须找到一种新的方法来限制用户的资源。如果没有保护此变量的方法,是否还有其他方法可以实现您可能建议的相同目标?

编辑2011-03-02 数据库向公众开放并允许任意SQL的原因是因为该项目适用于直接在数据库中玩的游戏。每个玩家都是数据库用户。数据被锁定在视图,规则和触发器后面,CREATE从public撤消,玩家角色可以防止对模式的大多数更改和pg_proc上的SELECT被删除以保护游戏敏感的功能代码。

这不是我向全世界开放的一些关键任务系统。这是一个奇怪的概念证明,它在数据库中放置了异常的信任量,试图在其中维护整个CIA安全三角形。

感谢您的帮助, Abstrct

2 个答案:

答案 0 :(得分:1)

没有办法覆盖这个。如果允许用户运行任意SQL命令,那么更改statement_timeout无论如何都只是冰山一角......如果你不信任你的用户,你不应该让他们运行任意SQL - 或接受他们可以运行好吧,任意SQL。并有一些取消查询的外部监视器。

答案 1 :(得分:0)

基本上,您不能在普通的postgres中执行此操作。 为了实现目标,您可以使用某种类型的代理并重写/禁止某些查询。

有几种解决方案,例如:

  1. db-query-proxy-article的出生方式(俄语)。
  2. BGBouncer + pgbouncer-rr-patch

最后包含非常useful examples,在Python上非常简单:

import re
def rewrite_query(username, query):
    q1="SELECT storename, SUM\(total\) FROM sales JOIN store USING \(storeid\) GROUP BY storename ORDER BY storename"
    q2="SELECT prodname, SUM\(total\) FROM sales JOIN product USING \(productid\) GROUP BY prodname ORDER BY prodname"
    if re.match(q1, query):
        new_query = "SELECT storename, SUM(total) FROM store_sales GROUP BY storename ORDER BY storename;"
    elif re.match(q2, query):
        new_query = "SELECT prodname, SUM(total) FROM product_sales GROUP BY prodname ORDER BY prodname;"
    else:
        new_query = query
    return new_query