私はSinatraを使用しており、認証にsinatra-authentication gemを使用しており、連絡先フォームなどのカスタムフォームも使用しています。
CSRFの問題を解決するために、sinatra-authenticationからの事前定義されたルートとカスタムルートで機能する小さなソリューションを考案しました。
before do
if request.post?
if session[:csrf] != params[:csrf]
halt 503, erb('<h1>500: oops</h1>')
end
end
time = Time.now.to_s
@key = Digest::SHA1.hexdigest(time)
session[:csrf] = @key
end
したがって、各ページリクエストで、現在の時刻のハッシュであるセッションを設定します。このハッシュも、非表示の要素を使用して各フォームに設定されます<input type="hidden" name="csrf" value="<%= @key %>" />
。フォームが送信されると、元のフォーム内before
で、セッションに保存されているアイテムと、送信されたアイテムが非表示の値としてチェックされます。単純!
しかし...これはローカルホストでは問題なく、herokuapp.comドメインでは問題なく、私のドメイン(herokuapp.comドメインのcname)では問題なく機能しますが、ドメイン(Aレコードwww
)では機能しません。 non-www
HerokuのIPセットの場合)。
私が見ることができる唯一の違いはnon-www
、DNSのAレコードを持つドメインがワニスヘッダーを設定しているように見えるので、どこかでワニスを通過する必要がありますが、セッションはrack.session内にあるため、ワニスがこれをフィルタリングしているかどうか疑問に思っていますアウト。
それで、最終的に、なぜif session[:csrf] != params[:csrf]
戻ってくるのtrue
ですか?