我正在构建我自己的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
我还需要做两件事:
QUERY_GOVERNOR_COST_LIMIT
替换为实际而不是估计超时,因此查询的运行时间不会超过2分钟。SET
命令。 有什么想法吗?
答案 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语句等的限制的可用性。