17

Sinatra と CORS を使用して、ドメイン A (hefty.burger.com) でファイルのアップロードを受け入れています。ドメイン B (fizzbuzz.com) には、A のルートにファイルをアップロードするフォームがあります。

options ルートと post ルートがあり、どちらも「/uploader」という名前です。

options '/uploader' do
  headers 'Access-Control-Allow-Origin' => 'http://fizz.buzz.com',
  'Access-Control-Allow-Methods' => 'POST'
  200
end 

post '/uploader' do
  ... 
  content_type :json
  [{:mary => 'little lamb'}].to_json
end

オプションが最初にヒットします...そして機能します..次に、投稿がヒットし、403が返されます.

保護を無効にすると、投稿は機能します...保護を維持しながらこれらの投稿を許可するには、リストからどのような保護を除外する必要がありますか?

私はつい最近、Heroku に影響を与えた新しい Rack 保護にやけどを負ってしまい、悲しみに暮れています... 誰かここで何をすべきかについての良い指針を持っていますか? 私がそう言う理由は、突然、セッション ハイジャックの問題に関する警告を含むログ エントリが表示されるようになったためです (ほぼ確実に、アプリに対して 1 つ以上の Dyno を実行しているだけです)。私はそれを要求したことはありませんが、Gemfile.lockにラック保護(1.2.0)が表示されます...マニフェストの何かがそれを呼び出しているため、ロードされますが、Sinatraアプリではそれを要求しようとさえしませんまたは設定します。

4

5 に答える 5

19

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::AuthenticityTokenRack::Protection::FormTokenRack::Protection::RemoteReferrer、および をRack::Protection::EscapedParams明示的に追加する必要があります)。

Sinatra は、1 つの例外を除いて Rack::Protection のデフォルト設定を使用します:セッションを有効にした場合のみ追加SessionHijackingします。RemoteToken

最後に、Sinatra で CORS を使用しようとしている場合は、多くの詳細を処理してくれるrack-corsを試すことができます。

于 2013-04-20T21:20:16.397 に答える
4

この問題が発生し、CORS (クロスオリジン リソース共有) を使用しておらず、リバース プロキシ (nginx や apache など) の背後にいる場合は、リバース プロキシがhostヘッダーを削除して置き換えていないことを確認してください。ローカルホストで。

たとえば、nginx では以下を使用する必要がありますproxy_set_header

location / {
    proxy_pass http://localhost:9296;
    proxy_set_header Host $host;
}

ヘッダーがリクエストから取り除かれると、Rack::Protection はそれが CSRF 攻撃であると認識します。

于 2016-02-26T03:57:42.213 に答える
3

Chromeアプリ「Dev HTTP Client」でテストしていると思いますか?代わりにこれを試してください:

curl -v -X POST http://fizz.buzz.com/uploader

ラック保護モジュールから: 「サポートされているブラウザー:: Google Chrome 2、Safari 4 以降」

これはうまくいくはずです:

class App < Sinatra::Base
  ...
  enable :protection
  use Rack::Protection, except: :http_origin
  use Rack::Protection::HttpOrigin, origin_whitelist: ["chrome-extension://aejoelaoggembcahagimdiliamlcdmfm", "http://fizz.buzz.com"]

  post '/uploader' do
    headers \
      'Allow'   => 'POST',
      'Access-Control-Allow-Origin' => 'http://fizz.buzz.com'
    body "it work's !"
  end

おそらくchrome-extension://aejoelaoggembcahagimdiliamlcdmfmについて疑問に思うでしょうか? それは、Chrome アプリで POST リクエストを送信したときにラック保護がenv['HTTP_ORIGIN']として取得するものです。

于 2013-01-26T00:04:36.047 に答える
1

これは、許可されたメソッドを options ルートに戻していないためですか?

ここでの質問は、許可されたメソッドを書き戻すことを参照しています。

ここの拡張機能とここのミドルウェアが役に立ちます。

于 2012-05-10T02:11:48.010 に答える
1

rack-protection では、2.0.0 以降のカスタム チェックを指定できます。

set :protection, :allow_if => lambda{ |env| env['HTTP_REFERER'] && URI(env['HTTP_REFERER']).host == 'fizz.buzz.com' }

https://github.com/sinatra/sinatra/blob/a2fe3e698b19ac4065f166f1727afd31d0e72f95/rack-protection/lib/rack/protection/json_csrf.rb#L39

于 2017-09-25T16:41:00.053 に答える