问题描述
我正在使用Sinatra和CORS接受域A(hefty.burger.com)上的文件上传.域B(fizzbuzz.com)具有一种将文件上传到A上的路由的表单.
I am using Sinatra and CORS to accept a file upload on domain A (hefty.burger.com). Domain B (fizzbuzz.com) has a form that uploads a file to a route on A.
我有一条选择路线和一条后继路线,都命名为'/uploader'.
I have an options route and a post route, both named '/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.
The options gets hit first... and it works.. then the post gets hit and returns a 403.
如果我禁用保护功能,则该帖子有效...我需要从列表中排除哪种保护才能保持保护,但允许这些帖子通过?
If I disable protection, the post works... what kind of protection do I need to exclude from a list to maintain protection but allow these posts through?
最近直到最近,我才被Heroku上新的Rack保护装置烧死,这让我有些悲痛……有人在这里做什么有很好的指示?我之所以这么说,是因为突然间,我看到带有会话劫持问题警报的日志条目(几乎可以肯定,这是因为该应用程序运行> 1 Dyno而已).我从未在Gemfile.lock中看到机架保护(1.2.0),尽管我从未要求过...清单中有东西在要求它,所以它已加载,但是我的Sinatra App中什么都没有尝试要求它或进行设置.
I have only recently been burned by the new Rack protection kicking in on Heroku and causing me some grief... anyone have a good pointer for what to do here? The reason I say that, is all of a sudden I am seeing log entries with alerts to session hijacking issues (almost certainly due to nothing more than running > 1 Dyno for the App). I see rack-protection (1.2.0) in my Gemfile.lock even though I never asked for it... something in my manifest is calling for it, so it is loaded, but nothing in my Sinatra App even tries to require it or set it up.
推荐答案
在您的Sinatra应用程序中使用它应该可以解决您的问题:
Using this in your Sinatra app should solve your problem:
set :protection, :except => [:json_csrf]
更好的解决方案可能是将Sinatra升级到1.4,该版本使用Rack :: Protection 1.5,并且不会导致您遇到的问题.
A better solution may be to upgrade Sinatra to 1.4, which uses Rack::Protection 1.5 and should not cause the problem you are seeing.
问题是您的RackProtection::JsonCsrf
版本与 CORS 不兼容您以Content-Type回应:application/json.这是 old json_csrf.rb 保护机架:
The problem is that your version of RackProtection::JsonCsrf
in is incompatible with CORS when you respond with Content-Type: application/json. Here is a snippet from the old json_csrf.rb in rack-protection:
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
响应的请求.
You can see this rejects requests that have an application/json
response when the referrer is not from the same host as the server.
此问题在更高版本的机架保护中得到了解决,该版本现在考虑请求是否为XMLHttpRequest:
This problem was solved in a later version of rack-protection, which now considers whether the request is an 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允许您完全禁用保护,或禁用Rack::Protection
的特定组件(请参阅配置攻击防护" ).
If you are using Sinatra 1.3.2 and cannot upgrade the solution is to disable this particular protection. With CORS you are explicitly enabling cross-domain XHR requests. Sinatra lets you disable protection entirely, or disable specific components of Rack::Protection
(see "Configuring Attack Protection" in the Sinatra docs).
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::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中间件(必须显式添加Rack::Protection::AuthenticityToken
,Rack::Protection::FormToken
,Rack::Protection::RemoteReferrer
和Rack::Protection::EscapedParams
)时,所有这些文件(只有四个)会自动加载.
At time of writing, all but four of these are loaded automatically when you use the Rack::Protection middleware (Rack::Protection::AuthenticityToken
, Rack::Protection::FormToken
, Rack::Protection::RemoteReferrer
, and Rack::Protection::EscapedParams
must be added explicitly).
Sinatra将Rack :: Protection的默认设置与一个例外:如果您启用了会话,则只会添加SessionHijacking
和RemoteToken
.
Sinatra uses Rack::Protection's default settings with one exception: it only adds SessionHijacking
and RemoteToken
if you enable sessions.
最后,如果您尝试将CORS与Sinatra一起使用,则可以尝试 rack-cors rack-cors ,它将为您处理很多细节.
And, finally, if you are trying to use CORS with Sinatra, you might try rack-cors, which takes care of a lot of the details for you.
这篇关于Sinatra和机架保护设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!