Rails 정품 토큰 이해
저는 Rails의 Authenticity Token과 관련하여 몇 가지 문제를 겪고 있습니다.
하지만 저는이 문제를 해결하고 계속하고 싶지 않습니다. 진정성 토큰을 이해하고 싶습니다. 제 질문은이 주제에 대한 완전한 정보 출처가 있습니까? 아니면 여기에서 자세히 설명하는 데 시간을 할애 하시겠습니까?
무슨 일이야
사용자가 리소스를 생성, 업데이트 또는 삭제하기 위해 양식을 볼 때 Rails 앱은 random을 생성 authenticity_token
하고이 토큰을 세션에 저장 한 다음 양식의 숨겨진 필드에 배치합니다. 사용자가 양식을 제출하면 Rails는를 찾아서 authenticity_token
세션에 저장된 것과 비교하고 일치하면 요청을 계속할 수 있습니다.
왜 일어나는가
인증 토큰이 세션에 저장되기 때문에 클라이언트는 그 값을 알 수 없습니다. 이는 사람들이 해당 앱 자체에서 양식을 보지 않고 Rails 앱에 양식을 제출하는 것을 방지합니다. 서비스 A를 사용하고 있고 서비스에 로그인했으며 모든 것이 정상이라고 가정 해보십시오. 이제 서비스 B를 이용하러 갔다가 좋아하는 사진을보고 더 큰 크기로보기 위해 사진을 눌렀다 고 상상해보십시오. 이제 서비스 B에 악의적 인 코드가있는 경우 서비스 A (로그인 한 상태)에 요청을 보내고에 요청을 보내 계정 삭제를 요청할 수 http://serviceA.com/close_account
있습니다. 이것이 CSRF (Cross Site Request Forgery) 로 알려진 것입니다 .
서비스 A가 인증 토큰을 사용하는 경우 서비스 B의 요청에 올바른 인증 토큰이 포함되지 않고 계속할 수 없으므로이 공격 벡터는 더 이상 적용되지 않습니다.
API 문서 는 메타 태그에 대한 세부 정보를 설명합니다.
CSRF 보호는
protect_from_forgery
토큰을 확인하고 예상 한 것과 일치하지 않는 경우 세션을 재설정하는 메서드 로 켜집니다 . 이 메소드에 대한 호출은 기본적으로 새로운 Rails 애플리케이션에 대해 생성됩니다. 토큰 매개 변수는authenticity_token
기본적으로 이름이 지정 됩니다. 이 토큰의 이름과 값은csrf_meta_tags
HTML 헤드 에 포함하여 양식을 렌더링하는 모든 레이아웃에 추가되어야합니다 .
메모
Rails는 멱 등성 메서드 (POST, PUT / PATCH 및 DELETE)가 아닌 것만 확인합니다. GET 요청은 인증 토큰에 대해 확인되지 않습니다. 왜? GET 요청을 HTTP 사양 상태는 나무 등입니다해야하고 있기 때문에 하지 , ALTER 만들거나 서버에서 자원을 파괴하고, 요청이 멱등해야한다 (같은 명령을 여러 번 실행하면, 당신은 동일한 결과를 모든 시간을 얻어야한다).
또한 실제 구현은 처음에 정의 된대로 조금 더 복잡하여 보안을 강화합니다. Rails는 모든 양식에 대해 동일한 저장된 토큰을 발행하지 않습니다. 매번 다른 토큰을 생성하고 저장하지도 않습니다. 세션에서 암호화 해시를 생성 및 저장하고 페이지가 렌더링 될 때마다 저장된 토큰과 일치 할 수있는 새 암호화 토큰을 발행합니다. request_forgery_protection.rb를 참조하십시오 .
레슨
authenticity_token
멱등이 아닌 메서드 (POST, PUT / PATCH 및 DELETE)를 보호하는 데 사용 합니다. 또한 서버의 리소스를 잠재적으로 수정할 수있는 GET 요청을 허용하지 않도록하십시오.
편집 : 멱등 성인 GET 요청에 대한 @erturne의 주석을 확인하십시오 . 그는 내가 여기서 한 것보다 더 나은 방식으로 그것을 설명합니다.
인증 토큰은 웹 사이트에서 양식이 제출되고 있음을 알 수 있도록 설계되었습니다. 컴퓨터에서만 알 수있는 고유 식별자를 사용하여 실행되는 컴퓨터에서 생성되므로 사이트 간 요청 위조 공격을 방지하는 데 도움이됩니다.
AJAX 스크립트 액세스를 거부하는 레일에 어려움이있는 경우 다음을 사용할 수 있습니다.
<%= form_authenticity_token %>
양식을 작성할 때 올바른 토큰을 생성하십시오.
자세한 내용은 문서 에서 읽을 수 있습니다 .
CSRF 란 무엇입니까?
정품 토큰은 CSRF (Cross-Site Request Forgery)에 대한 대책입니다. CSRF는 무엇입니까?
공격자가 세션 토큰을 몰라도 세션을 가로 챌 수있는 방법입니다.
시나리오 :
- 은행 사이트를 방문하여 로그인하십시오.
- 그런 다음 공격자의 사이트를 방문합니다 (예 : 신뢰할 수없는 조직의 후원 광고).
- 공격자의 페이지에는 은행의 "자금 이체"양식과 동일한 필드가있는 양식이 포함되어 있습니다.
- 공격자는 귀하의 계정 정보를 알고 있으며 귀하의 계정에서 공격자의 계정으로 돈을 이체하기 위해 미리 채워진 양식 필드를 가지고 있습니다.
- 공격자의 페이지에는 은행에 양식을 제출하는 자바 스크립트가 포함되어 있습니다.
- 양식이 제출되면 브라우저는 세션 토큰을 포함하여 은행 사이트에 대한 쿠키를 포함합니다.
- 은행은 공격자의 계좌로 돈을 이체합니다.
- 양식은 보이지 않는 iframe에있을 수 있으므로 공격이 발생했는지 알 수 없습니다.
- 이를 CSRF (Cross-Site Request Forgery)라고합니다.
CSRF 솔루션 :
- 서버는 서버 자체에서 가져온 양식을 표시 할 수 있습니다.
- 모든 양식에는 숨겨진 필드로 추가 인증 토큰이 포함되어야합니다.
- 토큰은 예측할 수 없어야합니다 (공격자가 추측 할 수 없음).
- 서버는 페이지의 양식에 유효한 토큰을 제공합니다.
- 서버는 양식이 게시 될 때 토큰을 확인하고 적절한 토큰이없는 양식은 거부합니다.
- 예시 토큰 : 서버 비밀 키로 암호화 된 세션 식별자.
- Rails는 이러한 토큰을 자동으로 생성합니다. 모든 형식의 authenticity_token 입력 필드를 확인하세요.
방지 할 수있는 최소 공격 예 : CSRF
내 웹 사이트 evil.com
에서 다음 양식을 제출하도록 설득합니다.
<form action="http://bank.com/transfer" method="post">
<p><input type="hidden" name="to" value="ciro"></p>
<p><input type="hidden" name="ammount" value="100"></p>
<p><button type="submit">CLICK TO GET PRIZE!!!</button></p>
</form>
세션 쿠키를 통해 은행에 로그인하면 쿠키가 전송되고 귀하도 모르는 사이에 송금이 이루어집니다.
이것이 바로 CSRF 토큰이 작동하는 것입니다.
- 양식을 반환 한 GET 응답으로 Rails는 매우 긴 임의의 숨겨진 매개 변수를 보냅니다.
- 브라우저가 POST 요청을 할 때 매개 변수를 함께 전송하고 서버는 일치하는 경우에만 수락합니다.
따라서 실제 브라우저의 양식은 다음과 같습니다.
<form action="http://bank.com/transfer" method="post">
<p><input type="hidden" name="authenticity_token" value="j/DcoJ2VZvr7vdf8CHKsvjdlDbmiizaOb5B8DMALg6s=" ></p>
<p><input type="hidden" name="to" value="ciro"></p>
<p><input type="hidden" name="ammount" value="100"></p>
<p><button type="submit">Send 100$ to Ciro.</button></p>
</form>
따라서 내 공격은 authenticity_token
매개 변수를 전송하지 않았기 때문에 실패 할 것이며 엄청난 난수이기 때문에 추측 할 수 없었습니다.
이 방지 기술을 Synchronizer Token Pattern 이라고 합니다 .
동일한 출처 정책
하지만 공격자가 자바 스크립트로 두 번의 요청을했다면 하나는 토큰을 읽고 두 번째는 전송을 요청하는 것일까 요?
동기화 토큰 패턴만으로는이를 방지 할 수 없습니다!
https://security.stackexchange.com/questions/8264/why-is-the-same-origin-policy-so-important/72569# 에서 설명했듯이 이것이 바로 동일한 출처 정책이 구출되는 곳입니다. 72569
Rails가 토큰을 보내는 방법
다루는 곳 : Rails : csrf_meta_tag는 어떻게 작동합니까?
원래:
form_tag
GET 양식이 아닌 경우 양식에 숨겨진 필드를 추가하는 것과 같은 HTML 도우미AJAX는 jquery-ujs에 의해 자동으로 처리됩니다. jquery-ujs 는
meta
헤더에 추가 된 요소csrf_meta_tags
(기본 템플릿에 있음)에서 토큰을 읽고 요청에 추가합니다.uJS는 또한 오래된 캐시 조각의 양식에서 토큰을 업데이트하려고합니다.
기타 예방 접근법
- 특정 헤더가 있는지 확인하십시오
X-Requested-With
. Origin
헤더 값 확인 : https://security.stackexchange.com/questions/91165/why-is-the-synchronizer-token-pattern-preferred-over-the-origin-header-check-to- 재 인증 : 사용자에게 비밀번호를 다시 요청합니다. 사이트가 XSS 된 경우를 대비하여 모든 중요한 작업 (은행 로그인 및 송금, 대부분의 웹 사이트에서 비밀번호 변경)에 대해이 작업을 수행해야합니다. 단점은 사용자가 암호를 여러 번 입력해야한다는 점입니다. 이는 번거롭고 키 로깅 / 숄더 서핑의 기회를 증가시킵니다.
은 Authenticity Token
레일 '하는 방법 방지 사이트 간 요청 위조 (CSRF 또는 XSRF) 공격' .
간단히 말해서, 웹 앱에 대한 PUT / POST / DELETE (콘텐츠를 수정할 수있는 방법) 요청이 생성 된 쿠키에 대한 액세스 권한이있는 제 3 자 (공격자)가 아닌 클라이언트의 브라우저에서 이루어 지도록합니다. 클라이언트 측에서.
인증 토큰은 CSRF (Cross-Site Request Forgery) 공격을 방지하는 데 사용됩니다. 인증 토큰을 이해하려면 먼저 CSRF 공격을 이해해야합니다.
CSRF
귀하가의 작성자라고 가정합니다 bank.com
. GET 요청으로 다른 계정으로 돈을 이체하는 데 사용되는 양식이 사이트에 있습니다.
해커는 서버에 HTTP 요청을 보낼 수 있습니다 GET /transfer?amount=$1000000&account-to=999999
.
잘못된. 해커 공격은 작동하지 않습니다. 서버는 기본적으로 생각할까요?
어? 이적을 시작하려는이 사람은 누구입니까? 확실히 계정 소유자가 아닙니다.
How does the server know this? Because there's no session_id
cookie authenticating the requester.
When you sign in with your username and password, the server sets a session_id
cookie on your browser. That way, you don't have to authenticate each request with your username and password. When your browser sends the session_id
cookie, the server knows:
Oh, that's John Doe. He signed in successfully 2.5 minutes ago. He's good to go.
A hacker might think:
Hmm. A normal HTTP request won't work, but if I could get my hand on that
session_id
cookie, I'd be golden.
The users browser has a bunch of cookies set for the bank.com
domain. Every time the user makes a request to the bank.com
domain, all of the cookies get sent along. Including the session_id
cookie.
So if a hacker could get you to make the GET request that transfers money into his account, he'd be successful. How could he trick you into doing so? With Cross Site Request Forgery.
It's pretty simply, actually. The hacker could just get you to visit his website. On his website, he could have the following image tag:
<img src="http://bank.com/transfer?amount=$1000000&account-to=999999">
When the users browser comes across that image tag, it'll be making a GET request to that url. And since the request comes from his browser, it'll send with it all of the cookies associated with bank.com
. If the user had recently signed in to bank.com
... the session_id
cookie will be set, and the server will think that the user meant to transfer $1,000,000 to account 999999!
Well, just don't visit dangerous sites and you'll be fine.
That isn't enough. What if someone posts that image to Facebook and it appears on your wall? What if it's injected into a site you're visiting with a XSS attack?
It's not so bad. Only GET requests are vulnerable.
Not true. A form that sends a POST request can be dynamically generated. Here's the example from the Rails Guide on Security:
<a href="http://www.harmless.com/" onclick="
var f = document.createElement('form');
f.style.display = 'none';
this.parentNode.appendChild(f);
f.method = 'POST';
f.action = 'http://www.example.com/account/destroy';
f.submit();
return false;">To the harmless survey</a>
Authenticity Token
When your ApplicationController
has this:
protect_from_forgery with: :exception
This:
<%= form_tag do %>
Form contents
<% end %>
Is compiled into this:
<form accept-charset="UTF-8" action="/" method="post">
<input name="utf8" type="hidden" value="✓" />
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
Form contents
</form>
In particular, the following is generated:
<input name="authenticity_token" type="hidden" value="J7CBxfHalt49OSHp27hblqK20c9PgwJ108nDHX/8Cts=" />
To protect against CSRF attacks, if Rails doesn't see the authenticity token sent along with a request, it won't consider the request safe.
How is an attacker supposed to know what this token is? A different value is generated randomly each time the form is generated:
A Cross Site Scripting (XSS) attack - that's how. But that's a different vulnerability for a different day.
since Authenticity Token
is so important, and in Rails 3.0+ you can use
<%= token_tag nil %>
to create
<input name="authenticity_token" type="hidden" value="token_value">
anywhere
Beware the Authenticity Token mechanism can result in race conditions if you have multiple, concurrent requests from the same client. In this situation your server can generate multiple authenticity tokens when there should only be one, and the client receiving the earlier token in a form will fail on it's next request because the session cookie token has been overwritten. There is a write up on this problem and a not entirely trivial solution here: http://www.paulbutcher.com/2007/05/race-conditions-in-rails-sessions-and-how-to-fix-them/
Methods Where authenticity_token
is required
authenticity_token
is required in case of idempotent methods like post, put and delete, Because Idempotent methods are affecting to data.
Why It is Required
It is required to prevent from evil actions. authenticity_token is stored in session, whenever a form is created on web pages for creating or updating to resources then a authenticity token is stored in hidden field and it sent with form on server. Before executing action user sent authenticity_token is cross checked with
authenticity_token
stored in session. Ifauthenticity_token
is same then process is continue otherwise it does not perform actions.
What is an authentication_token ?
This is a random string used by rails application to make sure that the user is requesting or performing an action from the app page, not from another app or site.
Why is an authentication_token is necessary ?
To protect your app or site from cross-site request forgery.
How to add an authentication_token to a form ?
If you are generating a form using form_for tag an authentication_token is automatically added else you can use <%= csrf_meta_tag %>
.
참고URL : https://stackoverflow.com/questions/941594/understanding-the-rails-authenticity-token
'Programing' 카테고리의 다른 글
What does in XML mean? (0) | 2020.09.28 |
---|---|
Java에서 JSON을 구문 분석하는 방법 (0) | 2020.09.28 |
데이터 속성으로 요소 선택 (0) | 2020.09.28 |
로컬 저장소와 쿠키 (0) | 2020.09.28 |
Node.js + Nginx-이제 무엇입니까? (0) | 2020.09.28 |