ActionControll :: UnlimitedAuthenticityToken


148

Dưới đây là một lỗi, do một biểu mẫu trong ứng dụng Rails của tôi gây ra:

Processing UsersController#update (for **ip** at 2010-07-29 10:52:27) [PUT]
  Parameters: {"commit"=>"Update", "action"=>"update", "_method"=>"put", "authenticity_token"=>"ysiDvO5s7qhJQrnlSR2+f8jF1gxdB7T9I2ydxpRlSSk=", **more parameters**}

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

Điều này xảy ra cho mọi người không getyêu cầu và, như bạn thấy, authenticity_tokenlà có.

Câu trả lời:


207

Tôi có cùng một vấn đề nhưng với các trang được lưu vào bộ nhớ cache. Các trang được đệm với mã thông báo xác thực cũ và tất cả các hành động bằng cách sử dụng phương thức post / put / xóa trong trường hợp được công nhận là cố gắng giả mạo. Lỗi (422 Thực thể không thể xử lý) đã được trả lại cho người dùng.

Giải pháp cho Rails 3:
Thêm:

 skip_before_filter :verify_authenticity_token  

hoặc như "sagivo" đã chỉ ra trong Rails 4 add:

 skip_before_action :verify_authenticity_token

Trên các trang làm bộ nhớ đệm.

Như @toobulkeh nhận xét đây không phải là một lỗ hổng trên :index, :shownhững hành động, nhưng hãy cẩn thận sử dụng này trên :put, :postcác hành động.

Ví dụ:

 caches_page :index, :show  
 skip_before_filter :verify_authenticity_token, :only => [:index, :show]

Tham khảo: http://api.rubyonrails.org/groupes/ActionControll/RequestForgeryProtection/ClassMethods.html

Lưu ý được thêm bởi barlop- Rails 4.2 không dùng nữa Skip_b Before_filter có lợi cho Skip_b Before_action https://guides.rubyonrails.org/4_2_release_notes.html "Họ phương thức * _filter đã bị loại bỏ khỏi tài liệu. gia đình phương pháp "

Đối với Rails 6 (như "collimarco" đã chỉ ra), bạn có thể sử dụng skip_forgery_protectionvà an toàn khi sử dụng nó cho API REST không sử dụng dữ liệu phiên.


3
Đó không phải là trường hợp, tôi không biết về caches_page trước bài viết của bạn. Nhưng tôi sẽ kiểm tra caches_page , cảm ơn.
Nikita Rybak

7
trong đường ray 4skip_before_action :verify_authenticity_token
Sagiv Ofek

88
Đây không phải là một lỗ hổng?
quantumpotato

6
đây không phải là một lỗ hổng trên :index, :showhành động. Nhưng hãy cảnh giác khi đưa điều này vào :put, :posthành động!
toobulkeh

14
mặc dù tôi đồng ý đôi khi bạn cần điều này (như có thể một lần trong đời) nhưng bạn cần nhận ra rằng bạn đang sửa chữa bảo mật bằng cách vô hiệu hóa bảo mật. Không được đề xuất
tương đương

77

Đối với tôi nguyên nhân của vấn đề này trong Rails 4 là một sự thiếu sót,

<%= csrf_meta_tags %>

Dòng trong bố trí ứng dụng chính của tôi. Tôi đã vô tình xóa nó khi tôi viết lại bố cục của mình.

Nếu điều này không có trong bố cục chính, bạn sẽ cần nó trong bất kỳ trang nào bạn muốn có mã thông báo CSRF.


2
Chúng tôi cũng đang nhận được lỗi này. Nhưng nó bị chặn lại. Đây có thể là lý do hoặc sẽ không có điều này ảnh hưởng đến mọi yêu cầu có lỗi?
Ryan-Neal Mes

@ Ryan-NealMes, nếu mẫu của bạn thiếu dòng đó, bạn sẽ gặp lỗi. Vì vậy, có thể một số mẫu của bạn có nó và những mẫu khác thì không.
James McMahon

1
@JamesMcMahon cảm ơn, tôi đã tìm ra trường hợp của tôi thực sự là do người dùng xóa cookie của họ hoặc có cookie bị chặn. Tải được học từ câu hỏi này!
Ryan-Neal Mes

61

Có một số nguyên nhân gây ra lỗi này, (liên quan đến Rails 4).

1. Kiểm tra <%= csrf_meta_tags %>hiện diện trong bố cục trang

2. kiểm tra mã thông báo xác thực đang được gửi bằng các cuộc gọi AJAX nếu sử dụng trình form_fortrợ giúp với remote: truetùy chọn. Nếu không, bạn có thể bao gồm dòng <%= hidden_field_tag :authenticity_token, form_authenticity_token %>với khối biểu mẫu.

3. Nếu yêu cầu đang được gửi từ trang được lưu trong bộ nhớ cache, hãy sử dụng bộ nhớ đệm phân đoạn để loại trừ một phần của trang gửi yêu cầu, button_tov.v. nếu không, mã thông báo sẽ bị cũ / không hợp lệ.

Tôi sẽ miễn cưỡng vô hiệu hóa bảo vệ csrf ...


csrf_meta_tags nên ở trong <head>? Làm thế nào tôi có thể chắc chắn rằng nó không xung đột với turbolinks?
lấp lánh

37

Chỉ cần thêm các authenticity_tokenhình thức cố định nó cho tôi.

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

3
Rails được cho là gửi mã thông báo theo mặc định. Chúng tôi không muốn chỉ định rõ ràng. Tôi cảm thấy mã thông báo được thay đổi bằng cách nào đó trong tình huống này ở đây.
Abhi

1
Tuy nhiên, nếu bạn đã xây dựng biểu mẫu của mình không sử dụng trình trợ giúp, bạn nên đặt biểu mẫu theo cách thủ công.
André Guimarães Sakata

30

Mã thông báo xác thực là một giá trị ngẫu nhiên được tạo trong chế độ xem của bạn để chứng minh yêu cầu được gửi từ một biểu mẫu trên trang web của bạn chứ không phải nơi nào khác. Điều này bảo vệ chống lại các cuộc tấn công CSRF:

http://en.wikipedia.org/wiki/Cross-site_Vquest_forgery

Kiểm tra xem khách hàng / IP đó là ai, có vẻ như họ đang sử dụng trang web của bạn mà không tải quan điểm của bạn.

Nếu bạn cần gỡ lỗi thêm, câu hỏi này là một nơi tốt để bắt đầu: Tìm hiểu mã thông báo xác thực Rails

Chỉnh sửa để giải thích: Điều đó có nghĩa là họ đang kêu gọi hành động để xử lý biểu mẫu của bạn mà không bao giờ hiển thị biểu mẫu của bạn trên trang web của bạn. Điều này có thể độc hại (giả sử đăng bình luận spam) hoặc nó có thể cho thấy khách hàng đang cố gắng sử dụng API dịch vụ web của bạn trực tiếp. Bạn là người duy nhất có thể trả lời rằng theo bản chất của sản phẩm và phân tích các yêu cầu của bạn.


1
Cảm ơn, nhưng tôi đã biết mã thông báo xác thực là gì. Kiểm tra xem khách hàng / IP đó là ai, có vẻ như họ đang sử dụng trang web của bạn mà không tải quan điểm của bạn. Xin lỗi, "không tải lượt xem" nghĩa là gì?
Nikita Rybak

1
Tôi có nghĩa là ai đó (có thể là người gửi thư rác) có thể gửi dữ liệu đến biểu mẫu của bạn mà không cần thông qua giao diện người dùng của ứng dụng. Chẳng hạn, có thể thực hiện việc này bằng cách sử dụng chương trình dòng lệnh, chẳng hạn như curl.
John Topley

John có nó chính xác đúng. Điều đó có nghĩa là họ đang kêu gọi hành động để xử lý biểu mẫu của bạn mà không bao giờ hiển thị biểu mẫu của bạn trên trang web của bạn. Điều này có thể độc hại (giả sử đăng bình luận spam) hoặc nó có thể cho thấy khách hàng đang cố gắng sử dụng API dịch vụ web của bạn trực tiếp. Bạn là người duy nhất có thể trả lời rằng theo bản chất của sản phẩm và phân tích các yêu cầu của bạn.
Winfield

Ok, tôi đã hiểu nhầm ý kiến ​​của Winfield. Tôi nghĩ ứng dụng không được cấu hình bằng cách nào đó để 'tải quan điểm của tôi' khi tôi sử dụng trình duyệt.
Nikita Rybak

1
Tôi cũng có suy nghĩ khác, những yêu cầu này bao gồm mã thông báo, nhưng nó không hợp lệ. Điều này có thể được gây ra bằng cách lưu trữ trang hiển thị biểu mẫu của bạn hoặc một cái gì đó khác có thể gây ra phiên bản cũ của biểu mẫu.
Winfield

26

ActionController::InvalidAuthenticityTokencũng có thể được gây ra bởi một proxy ngược được cấu hình sai. Đây là trường hợp nếu trong theo dõi ngăn xếp, bạn nhận được một dòng trông như thế nào Request origin does not match request base_url.

Khi sử dụng proxy ngược (chẳng hạn như nginx) làm người nhận cho yêu cầu HTTPS và truyền yêu cầu không được mã hóa đến phụ trợ (như ứng dụng Rails), phụ trợ (cụ thể hơn: Rack) mong muốn một số tiêu đề có thêm thông tin về yêu cầu khách hàng ban đầu để có thể áp dụng các nhiệm vụ xử lý và các biện pháp bảo mật khác nhau.

Thông tin chi tiết có sẵn tại đây: https://github.com/rails/rails/issues/22965 .

TL; DR: giải pháp là thêm một số tiêu đề:

upstream myapp {
  server              unix:///path/to/puma.sock;
}

location / {
  proxy_pass        http://myapp;
  proxy_set_header  Host $host;
  proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header  X-Forwarded-Proto $scheme;
  proxy_set_header  X-Forwarded-Ssl on; # Optional
  proxy_set_header  X-Forwarded-Port $server_port;
  proxy_set_header  X-Forwarded-Host $host;
}

Ồ, tôi đã tìm kiếm 3 giờ cho một giải pháp cho việc này, và đây là nó, cảm ơn!
evexoio

cảm ơn bạn rất nhiều 6 giờ cố gắng giải quyết vấn đề này trên đường ray
Joe Half Face

18

quá muộn để trả lời nhưng tôi tìm thấy giải pháp.

Khi bạn xác định bạn sở hữu biểu mẫu html thì bạn bỏ lỡ chuỗi mã thông báo xác thực sẽ được gửi đến bộ điều khiển vì lý do bảo mật. Nhưng khi bạn sử dụng trình trợ giúp biểu mẫu rails để tạo một biểu mẫu, bạn sẽ nhận được một cái gì đó như sau

<form accept-charset="UTF-8" action="/login/signin" method="post">
  <div style="display:none">
    <input name="utf8" type="hidden" value="&#x2713;">
    <input name="authenticity_token" type="hidden" 
      value="x37DrAAwyIIb7s+w2+AdoCR8cAJIpQhIetKRrPgG5VA=">
    .
    .
    .
  </div>
</form>

Vì vậy, giải pháp cho vấn đề này là thêm trường xác thực_token hoặc sử dụng trình trợ giúp biểu mẫu đường ray thay vì xóa, hạ cấp hoặc nâng cấp đường ray.


9

Nếu bạn đã thực hiện một rake rails:updatehoặc gần đây đã thay đổi config/initializers/session_store.rb, đây có thể là một triệu chứng của cookie cũ trong trình duyệt. Hy vọng rằng điều này được thực hiện trong dev / test (nó là dành cho tôi) và bạn chỉ có thể xóa tất cả các cookie trình duyệt liên quan đến tên miền được đề cập.

Nếu đây là sản phẩm và bạn đã thay đổi key, hãy xem xét thay đổi lại để sử dụng cookie cũ (<- chỉ là suy đoán).


Đúng! Đối với tôi, việc có một session_store.rb trống đã gây ra lỗi.
lafeber

6

Tôi đã có vấn đề này với các cuộc gọi javascript. Tôi đã sửa nó chỉ bằng cách yêu cầu jquery_ujs vào tệp application.js.


Đúng, tôi cũng có vấn đề này và tôi đã thêm jquery_ujs trong ứng dụng js. Nó đã làm việc.
Abhi

3

Chúng tôi có cùng một vấn đề, nhưng nhận thấy rằng nó chỉ dành cho các yêu cầu sử dụng http: // chứ không phải với https: //. Nguyên nhân là secure: truedo session_store:

Rails.application.config.session_store(
  :cookie_store,
  key: '_foo_session',
  domain: '.example.com',
  secure: true
)

Đã sửa lỗi bằng cách sử dụng HTTPS ~ ở mọi nơi :)


Tôi gặp phải điều này khi sử dụng rails s(không phải SSL) thay vì điểm cuối SSL mà tôi đã thiết lập để phát triển. Mãi đến khi đọc bình luận của bạn, tôi mới nhận ra mình đang làm gì. Khi tôi quay lại sử dụng SSL, mọi thứ bắt đầu hoạt động trở lại. Cảm ơn!
Karl Wilbur

1
Tôi phải đối mặt với vấn đề này trong phát triển. Thay vì secure: truetôi đã viếtsecure: !Rails.env.development?
murb

1

Đối với đường ray 5, tốt hơn là thêm protect_from_forgery prepend: truevào để bỏ quaverify_authentication_token


5
Tại sao? Bạn có thể thêm một tài liệu tham khảo?
kwerle


0

Tôi gặp vấn đề này và lý do là vì tôi đã sao chép và dán bộ điều khiển vào ứng dụng của mình. Tôi cần phải thay đổi ApplicationControllerthànhApplicationController::Base


0

Tôi đã có vấn đề tương tự trên localhost. Tôi đã thay đổi tên miền cho ứng dụng, nhưng trong URL và tệp lưu trữ vẫn có tên miền cũ. Đã cập nhật dấu trang trình duyệt và tệp lưu trữ của tôi để sử dụng tên miền mới và bây giờ mọi thứ đều hoạt động tốt.


0

Có thể bạn đã thiết lập NGINX cho HTTPS nhưng chứng chỉ của bạn không hợp lệ? Tôi đã có một vấn đề tương tự trong quá khứ và chuyển hướng từ http sang https đã giải quyết vấn đề


0

Tôi đã kiểm tra <% = csrf_meta_tags%> có mặt và xóa cookie trong trình duyệt làm việc cho tôi.


0

Theo khuyến nghị của Ngọn hải đăng Chrome để tải ứng dụng nhanh hơn, tôi đã đồng bộ hóa Javascript của mình:

views/layout/application.html.erb

<%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload', async: true %>

Điều này đã phá vỡ mọi thứ và nhận được lỗi Token đó cho các biểu mẫu từ xa của tôi. Loại bỏ async: truecác vấn đề cố định.


0

Câu trả lời này cụ thể hơn nhiều đối với Ruby on Rails, nhưng hy vọng nó sẽ giúp được ai đó.

Bạn cần bao gồm mã thông báo CSRF với mọi yêu cầu không NHẬN. Nếu bạn đã quen sử dụng JQuery, Rails có một thư viện trợ giúp được gọi là jquery-ujsxây dựng trên nó và thêm một số chức năng ẩn. Một trong những điều nó làm là tự động bao gồm mã thông báo CSRF trong mọi ajaxyêu cầu. Xem ở đây .

Nếu bạn rời khỏi nó như tôi đã làm, bạn có thể thấy mình có lỗi. Bạn chỉ có thể gửi mã thông báo theo cách thủ công hoặc sử dụng thư viện khác để giúp cạo mã thông báo khỏi DOM. Xem bài này để biết thêm chi tiết.


-1

Trong rails 5, chúng ta cần thêm 2 dòng mã

    skip_before_action :verify_authenticity_token
    protect_from_forgery prepend: true, with: :exception

-2

Cài đặt

gem 'remotipart' 

có thể giúp đỡ


3
mặc dù điều này có thể là câu trả lời, nhưng cũng rất hữu ích để bao gồm phần thiết yếu của câu trả lời và giải thích tại sao / cách thức hoạt động của nó.
Roy Lee

-15

Vấn đề được giải quyết bằng cách hạ cấp xuống 2.3.5 từ 2.3.8. (cũng như vấn đề khét tiếng 'Bạn đang được chuyển hướng.')


@Flip có lẽ là một ý tưởng để cập nhật câu trả lời được chấp nhận?
lafeber
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.