ActionController :: InvalidAuthenticityToken


148

아래는 내 Rails 애플리케이션의 양식으로 인한 오류입니다.

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):

이것은 모든 비 get요청에 대해 발생하며 보시 authenticity_token다시피 있습니다.

답변:


207

나는 같은 문제가 있었지만 페이지 캐시 된 페이지가있었습니다. 오래된 인증 토큰과 위조 시도로 인식되는 post / put / delete 메소드를 사용하는 모든 작업으로 페이지가 버퍼링되었습니다. 오류 (422 처리 할 수없는 엔티티)가 사용자에게 리턴되었습니다.

Rails 3 솔루션 :
추가 :

 skip_before_filter :verify_authenticity_token  

또는 Rails 4에서 "sagivo"가 지적한대로 다음을 추가하십시오.

 skip_before_action :verify_authenticity_token

캐싱을 수행하는 페이지에서.

@toobulkeh은 주석으로이상의 취약점이 아닌 :index, :show행동 만에이를 사용하여 조심 :put, :post행동.

예를 들면 다음과 같습니다.

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

참조 : http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

skip_before_action에 찬성하여 barlop- Rails 4.2에 의해 사용되지 않는 skip_before_filter https://guides.rubyonrails.org/4_2_release_notes.html "* _filter 메소드 계열은 문서에서 제거되었습니다. * _action에 대해서는 사용을 권장하지 않습니다. 방법 군 "

들어 레일 6 사용할 수있는 ( "collimarco"는 지적) skip_forgery_protection하고 세션 데이터를 사용하지 않는 REST API를 위해 그것을 사용하는 것이 안전하다는 것을.


3
사실이 아닐 수도 있습니다. 게시하기 전에 caches_page 를 몰랐 습니다. 하지만 caches_page 를 확인하겠습니다 . 감사합니다.
Nikita Rybak

7
4 일skip_before_action :verify_authenticity_token
Sagiv Ofek

88
이것이 취약점이 아닙니까?
quantumpotato

6
이것은 :index, :show동작에 대한 취약점이 아닙니다 . 그러나 이것을 :put, :post행동 에 두는 것에 조심하십시오 !
toobulkeh

14
비록 당신이 때때로 이것이 필요하다면 (일생에 한 번) 경우에 동의하지만 보안을 비활성화하여 보안을 수정하고 있음을 알아야합니다. 권장하지 않음
해당

77

나에게 Rails 4에서이 문제의 원인이 빠져있었습니다.

<%= csrf_meta_tags %>

내 주 응용 프로그램 레이아웃의 줄입니다. 레이아웃을 다시 쓸 때 실수로 삭제했습니다.

이것이 기본 레이아웃이 아닌 경우 CSRF 토큰을 원하는 모든 페이지에 필요합니다.


2
이 오류도 받고 있습니다. 그러나 간헐적이다. 이것이 원인 일 수 있습니까? 그렇지 않으면 오류가있는 모든 요청에 ​​영향을 미치지 않습니까?
Ryan-Neal Mes

@ Ryan-NealMes, 템플릿에 해당 줄이 없으면 오류가 발생합니다. 따라서 일부 템플릿에는있을 수 있고 다른 템플릿에는 없을 수도 있습니다.
James McMahon

1
@JamesMcMahon 감사합니다. 제 사건은 실제로 사용자가 쿠키를 지우거나 쿠키를 차단했기 때문에 발생하는 것으로 나타났습니다. 이 질문에서 배운 것들!
Ryan-Neal Mes

61

이 오류에는 몇 가지 원인이 있습니다 (레일 4 관련).

1. <%= csrf_meta_tags %>페이지 레이아웃에 존재

하는지 확인합니다. 2. 옵션 form_for과 함께 도우미를 사용하는 경우 AJAX 호출과 함께 진품 토큰이 전송되고 있는지 확인합니다 remote: true. 그렇지 않으면 <%= hidden_field_tag :authenticity_token, form_authenticity_token %>양식 블록이 있는 행을 포함 할 수 있습니다 .

3. 캐시 된 페이지에서 요청이 전송되는 경우 조각 캐싱 을 사용 하여 요청 button_to등 을 보내는 페이지의 일부를 제외하십시오 . 그렇지 않으면 토큰이 오래되었거나 유효하지 않습니다.

csrf 보호를 무효화하는 것을 꺼려합니다 ...


csrf_meta_tags는 <head>에 있어야합니까? 터보 링크와 충돌하지 않는지 어떻게 알 수 있습니까?
Sparkle

37

authenticity_token양식을 추가하면 문제가 해결 되었습니다.

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

3
Rails는 기본적으로 토큰을 보내야합니다. 명시 적으로 지정하고 싶지 않습니다. 이 상황에서 토큰이 어떻게 든 바뀌는 것을 느낍니다.
Abhi

1
그러나 도우미를 사용하지 않고 양식을 작성한 경우 수동으로 작성해야합니다.
André Guimarães Sakata

30

진위성 토큰은 다른 곳이 아닌 사이트의 양식에서 요청이 제출되었음을 증명하기 위해보기에서 생성 된 임의의 값입니다. 이것은 CSRF 공격으로부터 보호합니다 :

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

클라이언트 / IP가 누구인지 확인하십시오.보기를로드하지 않고 사이트를 사용중인 것 같습니다.

더 디버깅해야하는 경우이 질문을 시작하는 것이 좋습니다 . Rails 진위성 토큰 이해

설명하기 위해 편집 : 웹 사이트에서 양식을 렌더링하지 않고 양식 제출을 처리하기 위해 조치를 호출하고 있음을 의미합니다. 스팸 댓글 게시와 같이 악의적이거나 웹 서비스 API를 직접 사용하려는 고객을 나타낼 수 있습니다. 당신은 당신의 제품의 본질에 의해 그리고 당신의 요구를 분석함으로써 그것에 응답 할 수있는 유일한 사람입니다.


1
고마워,하지만 난 이미 진품 토큰이 무엇인지 알고 있습니다. 클라이언트 / IP가 누구인지 확인하십시오.보기를로드하지 않고 사이트를 사용중인 것 같습니다. 죄송합니다. "조회 불러 오기 없음"의 의미는 무엇입니까?
Nikita Rybak

1
누군가 (아마도 스패머)는 응용 프로그램의 사용자 인터페이스를 거치지 않고 양식에 데이터를 제출할 수 있음을 의미합니다. 예를 들어 curl과 같은 명령 행 프로그램을 사용하여이 작업을 수행 할 수 있습니다.
John Topley

존은 정확히 옳습니다. 웹 사이트에서 양식을 렌더링하지 않고도 양식 제출을 처리하기 위해 액션을 호출하고 있음을 의미합니다. 스팸 댓글 게시와 같이 악의적이거나 웹 서비스 API를 직접 사용하려는 고객을 나타낼 수 있습니다. 당신은 당신의 제품의 본질에 의해 그리고 당신의 요구를 분석함으로써 그것에 응답 할 수있는 유일한 사람입니다.
Winfield

좋아, 나는 윈필드의 의견을 오해했다. 브라우저를 사용할 때 앱이 어떻게 든 '보기를로드'하도록 구성되지 않았다고 생각했습니다.
Nikita Rybak

1
또 다른 생각이 있었는데, 이러한 요청에는 토큰이 포함되어 있지만 유효하지 않습니다. 양식을 렌더링하는 페이지 또는 양식의 오래된 버전을 잠재적으로 야기 할 수있는 다른 원인을 캐싱하면이 문제가 발생할 수 있습니다.
Winfield

26

ActionController::InvalidAuthenticityToken잘못 구성된 리버스 프록시로 인해 발생할 수도 있습니다. 스택 추적에서 다음과 같은 줄이 나타나는 경우 Request origin does not match request base_url입니다.

HTTPS 요청의 수신자로 리버스 프록시 (예 : nginx)를 사용하고 암호화되지 않은 요청을 백엔드 (예 : Rails 앱)로 전송하는 경우 백엔드 (보다 구체적으로 : 랙)는 원래 클라이언트 요청에 대한 자세한 정보가있는 일부 헤더를 예상합니다. 다양한 처리 작업 및 보안 조치를 적용 할 수 있습니다.

자세한 내용은 https://github.com/rails/rails/issues/22965에서 확인할 수 있습니다 .

TL; DR : 해결책은 헤더를 추가하는 것입니다.

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;
}

와우, 나는 이것에 대한 해결책을 찾기 위해 3 시간을 찾고 있었고 이것이 고마워했습니다!
evexoio

레일
Joe Half Face

18

대답하기에는 너무 늦었지만 해결책을 찾았습니다.

자신이 html 양식을 정의하면 보안상의 이유로 컨트롤러로 전송해야하는 인증 토큰 문자열이 누락됩니다. 그러나 rails form helper를 사용하여 양식을 생성하면 다음과 같은 결과가 나타납니다.

<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>

따라서 문제의 해결책은 authenticity_token 필드를 추가하거나 레일을 제거, 다운 그레이드 또는 업그레이드하는 대신 레일 폼 헬퍼를 사용하는 것입니다.


9

을 (를) 수행 rake rails:update했거나 최근에 변경 config/initializers/session_store.rb한 경우 브라우저에서 기존 쿠키의 증상 일 수 있습니다. 바라건대 이것은 dev / test (나를 위해)에서 이루어졌으며 문제의 도메인과 관련된 모든 브라우저 쿠키를 지울 수 있습니다.

이것이 생산 key중이고 변경 한 경우 이전 쿠키를 사용하도록 다시 변경하는 것이 좋습니다 (<-just speculation).


예! 나를 위해, session_store.rb가 비어 있으면 오류가 발생했습니다.
lafeber

6

자바 스크립트 호출 에서이 문제가 발생했습니다. jquery_ujs를 application.js 파일에 필요로 수정했습니다.


네 맞습니다.이 문제도 있었고 응용 프로그램 js에 jquery_ujs를 추가했습니다. 효과가있었습니다.
Abhi

3

동일한 문제가 있었지만 https : //가 아닌 http : //를 사용한 요청에만 해당되는 것으로 나타났습니다. secure: truesession_store 의 원인은 다음 과 같습니다.

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

HTTPS ~ everywhere를 사용하여 수정 :)


rails s개발을 위해 설정 한 SSL 엔드 포인트 대신 (비 SSL)을 사용할 때이 문제가 발생했습니다 . 내가하고있는 일을 깨달았다는 당신의 의견을 읽을 때까지는 아니 었습니다. SSL 사용으로 다시 전환하면 작업이 다시 시작되었습니다. 감사!
Karl Wilbur

1
개발 과정 에서이 문제에 직면했습니다. secure: true내가 쓴 대신secure: !Rails.env.development?
murb

1

레일 5의 경우, protect_from_forgery prepend: true건너 뛰는 것보다 추가하는 것이 좋습니다 verify_authentication_token


5
왜? 참조를 추가 할 수 있습니까?
kwerle


0

나는이 문제가 있었고 그 이유는 컨트롤러를 내 응용 프로그램에 복사하여 붙여 넣었 기 때문입니다. 나는 ~로 바꿔야 ApplicationController했다ApplicationController::Base


0

localhost에서 같은 문제가있었습니다. 앱의 도메인을 변경했지만 URL 및 호스트 파일에 여전히 기존 도메인이있었습니다. 새 도메인을 사용하도록 브라우저 책갈피 및 호스트 파일을 업데이트했으며 이제 모든 것이 제대로 작동합니다.


0

NGINX를 HTTPS 용으로 설정했지만 인증서가 유효하지 않습니까? 과거에 비슷한 문제가 있었고 http에서 https로 리디렉션하면 문제가 해결되었습니다.


0

<% = csrf_meta_tags %>가 있는지 확인하고 브라우저에서 쿠키를 지우면 나를 위해 일했습니다.


0

더 빠른 애플리케이션로드에 대한 Chrome Lighthouse 권장 사항에 따라 Javascript를 비 동기화했습니다.

views/layout/application.html.erb

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

이것은 모든 것을 깨뜨 렸고 내 원격 양식에 대한 토큰 오류가 발생했습니다. 제거 async: true하면 문제가 해결되었습니다.


0

이 답변은 Ruby on Rails에 훨씬 더 구체적이지만 누군가에게 도움이되기를 바랍니다.

비 GET 요청마다 CSRF 토큰을 포함해야합니다. JQuery를 사용하는 데 익숙하다면 Rails에는 jquery-ujs그 위에 빌드되고 숨겨진 기능을 추가 하는 도우미 라이브러리가 있습니다. 그것이하는 것 중 하나는 모든 ajax요청 에 자동으로 CSRF 토큰을 포함한다는 것 입니다. 여기를 참조하십시오 .

내가 한 것처럼 전환하지 않으면 오류가 발생할 수 있습니다. 토큰을 수동으로 제출하거나 다른 라이브러리를 사용하여 DOM에서 토큰을 폐기 할 수 있습니다. 자세한 내용은 이 게시물 을 참조하십시오 .


-1

5 번 레일에는 2 줄의 코드를 추가해야합니다

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

-2

설치

gem 'remotipart' 

도울 수있다


3
이것이 대답이 될 수도 있지만 대답의 필수 부분을 포함하고 그 이유 / 어떻게 작동하는지 설명하는 것도 도움이됩니다.
Roy Lee

-15

2.3.8에서 2.3.5로 다운 그레이드하여 문제가 해결되었습니다. (유명한 '당신이 리디렉션되고 있습니다.'문제뿐만 아니라)


@ 플립 아마도 대답을 받아 들일 생각입니까?
lafeber
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.