3

我正在开发一个使用Ruby on Rails的数据仓库,我应该允许用户在应用程序数据库上执行任意的SELECT查询。我知道这是你通常不应该做的,但它是我的客户端实际需要的接口(我想不出用户可能想要做的所有可能的查询并将它们转换为ActiveRecord查询)。可能有复杂的联接和子查询等。 我宁愿这样做(将其集成到我的应用程序),而不是让他们通过pgAdmin访问数据库(我使用postgresql)。用户生成的SQL查询

我的问题是:做这件事最安全的方法是什么?我应该能够逃脱任何东西像插入,更新,删除表等...

我想获取查询字符串和消毒这些“危险”的话,然后使用ActiveRecord :: Base.connection.execute (sanitized_sql_string)。 这是一个合理的方法吗?

+1

说得对,让用户**键入**自己的SQL是危险的。你可以锁定它们不能损坏你的数据库的权利,但你不能让它们不正确地连接表,这可能会产生一个失控的查询**。 Andyne(sp?)曾经有一种叫做GQL(图形查询语言)的产品,它允许用户点击对象和线条以图形方式创建查询。它在幕后完成了** good ** SQL的工作。您可以采取类似的方法,以便用户1)不必学习数据库模型; 2)不必知道SQL即可构建临时查询。 –

+0

您可能会更喜欢商店购买的产品,如水晶报表或商业对象。实际上,带有链接表的Microsoft Access并不是那么糟糕。 –

+0

我不知道,我可能一个人在这里,但我认为如果做得对,允许即席查询是完全正确的。这显然是一个强大的工具,仅供某些知道SQL的用户使用。一些蹩脚的编辑总是会有局限性;我还没有看到任何我觉得有用的东西。如果使用正确,Postgres中的安全性非常好,并且可以通过将查询超时设置为5秒或更长时间来避免*失控查询*。请记住,[StackOverflow](http://data.stackexchange.com/)实际上允许即席查询。 –

回答

3

最安全的方法是让Postgres为您处理这个安全问题。创建一个新用户:

CREATE USER Reader; -- Your Rails app should logon with this user 

然后,明确授予你希望他们能够查询的对象SELECT权限:

GRANT INSERT ON TableFoo TO Reader; 
GRANT INSERT ON TableBar TO Reader; 

然后,他们将能够运行任意SELECT来自这两个表的查询,但如果他们尝试INSERT,他们将得到权限被拒绝。然后,您可以捕获这些安全性异常并在您的UI中适当地处理它们。

+0

您需要对包含感兴趣表格的模式授予'GRANT'权限。这毫无疑问是正确的方法。不管你是否可以说服Rails以不同用途登录不同的用户,完全是另一回事,尽管.. –

+0

我喜欢这种方法。事情是,我需要访问具有不同连接的相同模型,所以最终我需要在非只读环境中执行查询(我使用查询结果更新其他模型)。我想要做的是在保存未来实际使用前,使用只读用户验证查询。这听起来合理吗? – pcarranzav

1

创建应用程序,然后创建数据库。

在此之后,在您的数据库配置(database.yml)中,用一些非默认用户(例如lame_user)连接到数据库。在你的RDBMS上创建lame_user,在你的情况下PostgreSQL,并授予他对你所有表的SELECT权限。
您现在将拥有可以访问您的数据库的用户postgreslame_user,但只有postgres可以完成所有工作。

如果用户试图做除SELECT之外的任何事情,则会发生错误。

恢复:使此应用程序约束数据库的东西。它会更容易。