2012-05-09 30 views
15

Tôi đang sử dụng Sinatra và CORS để chấp nhận tải lên tệp trên miền A (hefty.burger.com). Miền B (fizzbuzz.com) có biểu mẫu tải tệp lên tuyến đường trên A.Cài đặt bảo vệ Sinatra và Rack

Tôi có tuyến đường tùy chọn và tuyến đường bưu điện, cả hai đều có tên '/ người tải lên'.

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 

Các tùy chọn được hit đầu tiên ... và nó hoạt động .. thì bài bị đánh và trả về một 403.

Nếu tôi vô hiệu hóa bảo vệ, các bài hoạt động ... những loại bảo vệ làm Tôi cần loại trừ khỏi danh sách để duy trì bảo vệ nhưng cho phép các bài đăng này thông qua?

Tôi chỉ mới bị đốt cháy bởi chiếc bảo vệ Rack mới đá vào Heroku và khiến tôi đau buồn ... bất cứ ai có một con trỏ tốt để làm gì ở đây? Lý do tôi nói rằng, là tất cả của một đột ngột tôi nhìn thấy mục đăng nhập với cảnh báo cho các vấn đề cướp session (gần như chắc chắn do không có gì hơn chạy> 1 Dyno cho App). Tôi thấy rack-bảo vệ (1.2.0) trong Gemfile.lock của tôi mặc dù tôi không bao giờ yêu cầu nó ... một cái gì đó trong biểu hiện của tôi đang kêu gọi nó, vì vậy nó được nạp, nhưng không có gì trong ứng dụng Sinatra của tôi thậm chí cố gắng yêu cầu nó hoặc thiết lập nó.

+1

Nếu bạn có đăng nhập được kích hoạt nó sẽ hiển thị mà bảo vệ là trách nhiệm, một cái gì đó như 'tấn công ngăn ngừa bằng cách RemoteToken' (với lời mở đầu logger trước nó). – matt

+0

Tôi thấy điều này trên Rack Protection 1.5.3. Nó không xảy ra với Rack Protection eb7e4c9a176d. –

Trả lời

1

Đây có phải là vì bạn không trả lại các phương thức được phép trở lại trong tuyến đường tùy chọn của bạn?

Câu hỏi here đề cập đến nó ghi lại các phương thức được phép trở lại.

Một phần mở rộng here và phần mềm trung gian here có thể giúp bạn.

+1

Không, tôi đang đặt các tùy chọn chính xác. Tôi cho phép POST một cách rõ ràng và POST trả về 403 bị cấm. Tôi không chắc chắn một phần của bảo vệ rack là kiểm soát đó. Các tài liệu không rõ ràng và dường như không chứa bất cứ điều gì liên quan đến CORS. –

+1

David, tôi phải ở trong không gian đêm qua. Bạn có thể thử thiết lập, 'sử dụng Rack :: Protection,: except =>: json_csrf'? Ai đó có một vấn đề về rack :: bảo vệ git repo [về Rack :: Protection và CORS] (https://github.com/rkh/rack-protection/issues/14) là tốt. – al3xnull

3

Hãy để tôi đoán, bạn đang thử nghiệm với ứng dụng Chrome 'Dev HTTP Client'? Hãy thử điều này thay vì:

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

Từ các mô-đun bảo vệ giá: "Hỗ trợ các trình duyệt Google Chrome :: 2, Safari 4 và sau đó"

này nên làm việc:

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 

Bạn có thể thắc mắc về chrome-extension: // aejoelaoggembcahagimdiliamlcdmfm? Vâng, đó là những gì bảo vệ rack được như env ['HTTP_ORIGIN'] khi bạn gửi yêu cầu POST bằng ứng dụng Chrome.

+1

Trong ứng dụng Sinatra mới, tôi phải thay đổi 'sử dụng Rack :: Protection :: HttpOrigin, origin_whitelist: [" chrome-extension: // aejoelaoggembcahagimdiliamlcdmfm "," http://fizz.buzz.com "]' ĐỂ 'bộ: bảo vệ, origin_whitelist: ['chrome-extension: // aejoelaoggembcahagimdiliamlcdmfm']' –

17

Sử dụng này trong ứng dụng Sinatra của bạn nên giải quyết vấn đề của bạn:

set :protection, :except => [:json_csrf] 

Một giải pháp tốt hơn có thể được nâng cấp Sinatra đến 1,4, trong đó sử dụng rack :: Protection 1.5 và không nên gây the problem bạn đang nhìn thấy.

Vấn đề là phiên bản RackProtection::JsonCsrf của bạn không tương thích với CORS khi bạn trả lời bằng Content-Type: application/json. Dưới đây là một đoạn trích từ old json_csrf.rb trong rack bảo vệ:

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 

Bạn có thể thấy điều này từ chối yêu cầu có một phản ứng application/json khi giới thiệu không phải là từ cùng một máy chủ như máy chủ.

Vấn đề này đã được giải quyết trong một phiên bản sau của rack bảo vệ, mà bây giờ xem xét việc yêu cầu là một 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 

Nếu bạn đang sử dụng Sinatra 1.3.2 và không thể nâng cấp giải pháp là để vô hiệu hóa sự bảo vệ đặc biệt này. Với CORS, bạn rõ ràng cho phép yêu cầu XHR xuyên miền. Sinatra cho phép bạn tắt hoàn toàn bảo vệ hoặc vô hiệu hóa các thành phần cụ thể của Rack::Protection (xem "Configuring Attack Protection" trong tài liệu Sinatra).

Rack::Protection cung cấp 12 middleware components giúp đánh bại các cuộc tấn công thông thường:

  • 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

Tại thời điểm viết bài, tất cả nhưng bốn trong số này được nạp tự động khi bạn sử dụng Rack :: Phần mềm trung gian bảo vệ (Rack::Protection::AuthenticityToken, Rack::Protection::FormToken, Rack::Protection::RemoteReferrerRack::Protection::EscapedParams phải được thêm một cách rõ ràng).

Sinatra sử dụng Rack :: Cài đặt mặc định của Protection với one exception: chỉ thêm SessionHijackingRemoteToken nếu bạn bật phiên.

Và cuối cùng, nếu bạn đang cố gắng sử dụng CORS với Sinatra, bạn có thể thử rack-cors, công cụ này sẽ giải quyết rất nhiều chi tiết cho bạn.

+0

Nhưng trong tập tin nào bạn đặt dòng đó? Gây nhầm lẫn. – AKWF

2

Nếu bạn thấy vấn đề này, bạn không sử dụng CORS (chia sẻ tài nguyên gốc), và đằng sau proxy ngược (như nginx hoặc apache), hãy đảm bảo rằng proxy ngược của bạn không bị loại bỏ host tiêu đề và thay thế bằng localhost.

Ví dụ, trong nginx bạn cần phải sử dụng proxy_set_header:

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

Khi header được tước ra từ một yêu cầu, Rack :: Bảo vệ tin rằng nó là một cuộc tấn công CSRF.

+0

Bài đăng của bạn giống như một chiếc găng tay cho kiến ​​trúc của tôi, nhưng thêm 'proxy_set_header Host $ host;' vào cấu hình nginx của tôi, đã không giải quyết nó. – bonafernando

Các vấn đề liên quan