Sinatra アプリでこれを使用すると、問題が解決するはずです。
set :protection, :except => [:json_csrf]
より良い解決策は、Rack::Protection 1.5 を使用する Sinatra を 1.4 にアップグレードすることであり、あなたが見ている問題を引き起こすことはありません。
問題は、Content-Type: application/json で応答すると、inのバージョンがCORSRackProtection::JsonCsrf
と互換性がないことです。以下は、rack-protectionの古い json_csrf.rbのスニペットです。
def call(env)
status, headers, body = app.call(env)
if headers['Content-Type'].to_s.split(';', 2).first =~ /^\s*application\/json\s*$/
if referrer(env) != Request.new(env).host
result = react(env)
warn env, "attack prevented by #{self.class}"
end
end
result or [status, headers, body]
end
application/json
リファラーがサーバーと同じホストからのものではない場合、これにより、応答のある要求が拒否されることがわかります。
この問題は、その後のバージョンの rack-protection で解決され、リクエストが XMLHttpRequest であるかどうかが考慮されるようになりました。
def has_vector?(request, headers)
return false if request.xhr?
return false unless headers['Content-Type'].to_s.split(';', 2).first =~ /^\s*application\/json\s*$/
origin(request.env).nil? and referrer(request.env) != request.host
end
Sinatra 1.3.2 を使用していてアップグレードできない場合、解決策はこの特定の保護を無効にすることです。CORS を使用すると、クロスドメイン XHR リクエストを明示的に有効にできます。Sinatra では、保護を完全に無効にすることも、特定のコンポーネントを無効にすることもできます( Sinatra ドキュメントの「攻撃保護の構成」Rack::Protection
を参照してください)。
Rack::Protection
は、一般的な攻撃を打ち負かすのに役立つ12 のミドルウェア コンポーネントを提供します。
Rack::Protection::AuthenticityToken
Rack::Protection::EscapedParams
Rack::Protection::FormToken
Rack::Protection::FrameOptions
Rack::Protection::HttpOrigin
Rack::Protection::IPSpoofing
Rack::Protection::JsonCsrf
Rack::Protection::PathTraversal
Rack::Protection::RemoteReferrer
Rack::Protection::RemoteToken
Rack::Protection::SessionHijacking
Rack::Protection::XssHeader
執筆時点では、Rack::Protection ミドルウェアを使用すると、これらのうち 4 つを除くすべてが自動的にロードされます ( Rack::Protection::AuthenticityToken
、Rack::Protection::FormToken
、Rack::Protection::RemoteReferrer
、および をRack::Protection::EscapedParams
明示的に追加する必要があります)。
Sinatra は、1 つの例外を除いて Rack::Protection のデフォルト設定を使用します:セッションを有効にした場合のみ追加SessionHijacking
します。RemoteToken
最後に、Sinatra で CORS を使用しようとしている場合は、多くの詳細を処理してくれるrack-corsを試すことができます。