2017-01-05 2 views
0

Postgres High(PSD 9.6)では、オードとグライ・クラブは奇妙な共依存戦争に陥っています。オタクは喜んでクラブに秘密の計画を描く。グライクラブは楽しい歌で応えます。Postgres Highのプリンシパル・リスク

オードが暴れると、グライクラブは決して反応しません。同様に、オタクは喜んクラブからリールを取得しようとしているだけなので、喜んでクラブが応答しない場合、オタクは実際に彼らの秘密の計画を呼び出すことはありません。

プリンシパルプログラマーとして、一度に起こりうるオタクの反乱の試みが1つしかないようにすることが私の仕事です。私はまた、オタクが成功し、グライクラブが成功するか、どちらも成功しないようにする必要があります。しかし、それらの は面倒なオタク、常に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に行がないかもしれない)、グリークラブはとにかく歌うだろう。

2つのコマンドをデータ変更CTEで連鎖させることも、挿入を更新の成功に依存させる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); 

機能はアトミックなので、それはすべてが起こるか、それが起こったことはありません。
パラメータはの値(prepared statementとよく似ている)として渡されるため、SQLインジェクションの機会はありません。

関連:

+0

このような状況では、機能レベルでのアトミック性の制御は簡単です。ありがとうございました。 VPを雇い、「Burt_the_Nerd_Striker」と呼び、校長として責任を委任します。私の心のコンテンツにコーヒーとドーナツ。アーウィンに参加することを歓迎します。あなたに貸しがある。 – bbuckley123

関連する問題