实施查询限制

时间:2009-09-18 02:36:54

标签: sql-server sql-server-2005 security

我正在构建我自己的http://statoverflow.com/sandbox克隆(使用free controls provided to 10K users from Telerik)。我有一个可以在本地使用的概念证明,但在我向其他人开放之前,我需要将其锁定一些。目前,我通过类似这样的存储过程运行所有内容:

CREATE PROCEDURE WebQuery 
    @QueryText nvarchar(1000)
AS
BEGIN
    -- no writes, so no need to lock on select
    SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED 

    -- throttles
    SET ROWCOUNT 500 
    SET QUERY_GOVERNOR_COST_LIMIT 500

    exec (@QueryText)

END

我还需要做两件事:

  1. QUERY_GOVERNOR_COST_LIMIT替换为实际而不是估计超时,因此查询的运行时间不会超过2分钟。
  2. 现在没有什么能阻止用户自己设置'SET ROWCOUNT 50000;'在他们的查询文本前面覆盖我的限制,所以我需要以某种方式将查询限制为单个语句或(最好)不允许exec函数内的SET命令。
  3. 有什么想法吗?

3 个答案:

答案 0 :(得分:3)

您真的打算允许用户运行任意Ad-Hoc SQL吗?只有这样,用户才能置于SET中以覆盖您的限制。如果是这种情况,最好的办法是使用lexx / yacc或flex / bison(或您喜欢的CLR语言树解析器)进行一些基本的解析,并检测无效的SET语句。你是否会允许SET @variable=value,语法上 SET ......

如果您通过EXECUTE AS模拟低特权用户,请确保创建不可逆模拟上下文,这样用户不会简单地执行REVERT并重新获得所有权限:)您还必须确实了解数据库模拟的含义,请务必阅读Extending Database Impersonation by Using EXECUTE AS

要考虑的另一件事是对队列的请求执行。由于队列阅读器可以通过MAX_QUEUE_READERS进行校准,因此您可以获得非常便宜的限制。有关如何使用队列执行批处理的相关文章,请参阅Asynchronous procedure execution。这种机制与资源治理不同,但我已经看到它曾经更多地影响了调控器本身。

答案 1 :(得分:0)

在一个非常基础的层面上,如何阻止任何不以SELECT开头的语句?或者是否支持其他查询,如CTE或DECLARE语句? 1000个字符并没有太大的空间可以玩,但我不太清楚这首先是什么。

已更新

好的,如何使用SELECT TOP 500 FROM(

)为他们提交的内容添加前缀

并附上a)。如果他们试图做多个语句,它会抛出一个你可以捕获的错误。并且为了防止拒绝服务,将其起始SELECT替换为另一个SELECT TOP 500。

如果他们将ORDER BY附加到返回一百万行的内容中,则无济于事。

答案 2 :(得分:0)

把它扔出去:

EXEC声明似乎支持假冒。见http://msdn.microsoft.com/en-us/library/ms188332.aspx。也许你可以冒充有限的用户。我正在研究可能阻止SET语句等的限制的可用性。