at posts/single.html

Amazon API認証リバースプロキシの不具合修正

結論から言うと、 Sinatra が使っている Rack::Protection::SessionHijacking ではまったという話。

さくらVPSサーバの移転にともなって、 machu.jp で動かしている Amazon API認証プロキシの設定を変えようと思い、Product Advertising API用リバースプロキシにアクセスしたら、更新処理が動かなくなっていた。 ログを見ると、更新処理のところでこんなログが出ている。

app web.1 - - attack prevented by Rack::Protection::SessionHijacking

Rack::Protection::SessionHijacking で検索すると Rubyで安全なWebアプリを作るためのメモ (2) | monoの開発ブログが見つかった。

Rack::Protection::SessionHijacking 初回アクセス時にUser-Agent・Accept-Encoding・Accept-Languageヘッダの内容をsession内に記憶しておき、一致しなくなった場合にセッションハイジャッキングが行われたと判断します。セッションハイジャッキングツールのFiresheepによる攻撃を防ぐのに有効なようです。しかし、ドキュメントにも書いてあるようにすべての攻撃を防げるものではないので、一般的なセッションハイジャッキング対策とあわせて利用すべきです。

なるほど。 HTTP リクエストヘッダを見て一意性をチェックしているのか。これらのヘッダをログに出力してみる。

通常の GET リクエスト時。

GET /css/smoothness/jquery-ui-1.8.16.custom.css
HTTP_USER_AGENT: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.3 Safari/536.11
HTTP_ACCEPT_ENCODING: gzip
HTTP_ACCEPT_LANGUAGE: ja,en-US;q=0.8,en;q=0.6

更新処理の時。

PUT /profile/4e848b36ddebc70001000001
HTTP_USER_AGENT: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_3) AppleWebKit/536.11 (KHTML, like Gecko) Chrome/20.0.1132.3 Safari/536.11
HTTP_ACCEPT_ENCODING: gzip,deflate,sdch
HTTP_ACCEPT_LANGUAGE: ja,en-US;q=0.8,en;q=0.6

HTTP_ACCEPT_ENCODING の値が GET と PUT で異なっている。このため、 Rack::Protection::SessionHijacking がセッション乗っ取りと判断してセッションを無効にしていたんだろう。

とりあえず、Sinatra側でこの機能を無効にして対応。

set :protection, except: :session_hijacking

しかし、以前にライブラリをバージョンアップしてから、ずっとこの状態だったんだろうなぁ…。

関連する日記