Применять ограничения запросов - PullRequest
3 голосов
/ 18 сентября 2009

Я создаю свой собственный клон http://statoverflow.com/sandbox (используя бесплатные элементы управления, предоставленные 10K пользователям из 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;» перед их текстом запроса, чтобы переопределить мое ограничение, поэтому мне нужно каким-то образом ограничить запросы одним оператором или (предпочтительно) запретить команды SET внутри функции exec.

Есть идеи?

Ответы [ 3 ]

3 голосов
/ 18 сентября 2009

Вы действительно планируете разрешить пользователям запускать произвольный Ad-Hoc SQL? Только тогда пользователь может поместить в набор, чтобы отменить ваши ограничения. Если это так, лучше всего выполнить базовый анализ с использованием lexx / yacc или flex / bison (или вашего любимого синтаксического анализатора языка CLR) и обнаружить недопустимые операторы SET. Вы собираетесь разрешить SET @variable=value, что синтаксически равно a SET ...

Если вы олицетворяете пользователей с низкими привилегиями через EXECUTE AS, убедитесь, что вы создали необратимый контекст олицетворения, чтобы пользователь не просто выполнял REVERT и восстанавливал все привилегии :) Вы также действительно должен понимать последствия олицетворения базы данных, обязательно прочитайте Расширение олицетворения базы данных с помощью EXECUTE AS .

Еще одна вещь, которую следует учитывать, - задерживать выполнение запросов в очереди. Поскольку средства чтения очереди могут быть откалиброваны с помощью MAX_QUEUE_READERS , вы получите очень дешевое регулирование. См. Асинхронное выполнение процедуры для связанной статьи о том, как использовать очереди для выполнения пакетов. Этот механизм отличается от управления ресурсами, но я видел, что он использовал для большего эффекта, чем сам губернатор.

0 голосов
/ 18 сентября 2009

Бросив это туда:

Похоже, что выражение EXEC поддерживает олицетворение. См. http://msdn.microsoft.com/en-us/library/ms188332.aspx. Возможно, вы можете выдать себя за ограниченного пользователя. Я изучаю наличие ограничений, которые могут помешать операторам SET и т. П.

0 голосов
/ 18 сентября 2009

На базовом уровне, как насчет блокировки любого оператора, который не начинается с SELECT? Или будут поддерживаться другие запросы, такие как операторы CTE или DECLARE? 1000 символов не слишком много места, чтобы играть, но я не очень понимаю, что это вообще.

ОБНОВЛЕНО

Хорошо, как насчет префикса, который они отправляют, с помощью SELECT TOP 500 FROM (

и добавление а). Если они попытаются сделать несколько утверждений, это выдаст ошибку, которую вы можете поймать. А чтобы предотвратить отказ в обслуживании, замените их начальный SELECT другим SELECT TOP 500.

Не помогает, если они добавили ORDER BY к чему-то, возвращающему миллион строк.

...