2017-01-05 7 views
0

В Postgres High (PSD 9.6) кретины и клуб ликования находятся в странной совместной войне. Бойцы замышляют тайные планы против ликования клуба. Клуб ликования отвечает приятными песнями.Основная опасность на высоком уровне Postgres

Клуб ликования никогда не отреагирует, если ботаники опустошат. Точно так же ботаники только пытаются вырваться из клуба ликования, поэтому, если ликующий клуб не сможет ответить, ботаники фактически не будут ссылаться на их секретный план.

И как главный программист, это моя работа, чтобы убедиться, что только одна возможная попытка восстания ботаника происходит одновременно. Я также должен убедиться, что оба ботаника преуспевают, и ликование клуба преуспевает или не преуспевает. Но эти проблемных ботаников, всегда пробующих атаки на SQL-инъекции. Должен также предотвратить это. И поскольку все хорошие лидеры Postgres High делают, мы пишем наши планы уроков в SQL.

План урока:

begin; 
-- stop race conditions with a hall monitor 
select from semaphore where name = 'hall_monitor' for update; 

prepare nerd_rebellion (
    text, -- secret_mission 
    date -- when_we_strike 
) as 
    update ultimate_plan 
    set secret_mission = $1 
    where when_we_strike = $2; 

prepare glee_club_counterstrike (
    text, -- happy_song 
    boolean -- kill_them_with_love 
) as 
    insert into song_therapy (
    happy_song, 
    kill_them_with_love 
) values (
    $1, 
    $2 
) 

execute nerd_rebellion(
    'Nerds do stuff like this ; drop table song_therapy --f you glee club', 
    '2017-01-01' 
); 
execute glee_club_counterstrike(
    'god_bless_america', 
    true 
); 
-- let us never speak of this again ... 
deallocate nerd_rebellion 
deallocate glee_club_counterstrike 

-- all done. Release the hall monitor 
commit; 

Гоша это много принципала сделать. Наши занятия в классе настолько коротки, что мы все готовим и освобождаем. Тьфу. На самом деле нарезает мой кофе и время пончика. Но мне нужно обернуть несколько операторов в одной транзакции и сериализовать с помощью семафора. Невозможно скомпрометировать и SQL-инъекцию. Я не вижу более простого решения. Вы?

+1

Люди не получают его, это, вероятно, будет закрыт в ближайшее время. Мне нравится этот вопрос. –

ответ

2

Вы не удостоверились, что ботаники преуспевают. Ботаны могут вычеркнуть (UPDATE не найдет ни одной строки), ликование клуба все равно будет петь.

Вы можете связать две команды с помощью CTW, модифицирующими данные, или в функции plpgsql, где вы можете вставить вставку в зависимости от успеха обновления.

Вот это инструмент основной можно использовать:

CREATE OR REPLACE FUNCTION nerd_strike(
     _secret_mission  text 
    , _when_we_strike  date 
    , _happy_song   text 
    , _kill_them_with_love boolean 
    ) RETURNS void AS 
$func$ 
BEGIN 
    SELECT FROM semaphore WHERE name = 'hall_monitor' FOR UPDATE; 

    UPDATE ultimate_plan 
    SET secret_mission = _secret_mission 
    WHERE when_we_strike = _when_we_strike; 

    IF FOUND THEN -- only if update actually succeeded 
     INSERT INTO song_therapy (happy_song, kill_them_with_love) 
     VALUES (_happy_song, _kill_them_with_love); 
    END IF; 
END 
$func$ LANGUAGE plpgsql; 

Вызов:

SELECT nerd_strike('Nerds do stuff like this ; drop table song_therapy --f you glee club' 
       , '2017-01-01' 
       , 'god_bless_america' 
       , true); 

Функции атомное, так что все это происходит или это никогда не случалось.
Параметры передаются как значения (так же, как с подготовленными операторами), поэтому нет возможности для SQL-инъекции.

Похожие:

+0

Управление атомарностью на уровне функции в таком случае просто великолепен. Спасибо. Я нанял вице-президента, назову его «Burt_the_Nerd_Striker» и делегировать ответственность в качестве Принципала. Кофе и пончики до моего сердца. Ты можешь присоединиться ко мне, Эрвин. Я твой должник. – bbuckley123

Смежные вопросы