저는 Rails API 로 간단한 API를 구축하고 있으며 여기에서 올바른 방향으로 가고 있는지 확인하고 싶습니다. 로그인을 처리하기 위해 devise를 사용하고 token_authenticatable
있으며 각 요청과 함께 보내야하는 API 키를 생성하는 Devise의 옵션 을 사용하기로 결정했습니다 .
API를 백본 / 마리오네트 프런트 엔드와 페어링하고 있으며 일반적으로 세션을 어떻게 처리해야하는지 궁금합니다. 내 첫 번째 생각은 로컬 저장소 또는 쿠키에 api 키를 저장하고 페이지로드시 검색하는 것이었지만 보안 관점에서 api 키를 저장하는 것에 대한 무언가가 나를 괴롭 혔습니다. 로컬 저장소 / 쿠키를 찾거나 전달되는 요청을 스니핑하여 API 키를 가져 와서 해당 사용자를 무기한으로 가장하는 데 사용하는 것이 쉽지 않을까요? 현재는 로그인 할 때마다 api 키를 재설정하고 있지만 그럴 경우에도 자주 보입니다. 어떤 기기에서든 로그인 할 때마다 다른 기기에서 모두 로그 아웃된다는 의미입니다. 이는 일종의 고통입니다. 이 재설정을 취소 할 수 있다면 사용성 관점에서 개선 될 것 같습니다.
나는 여기에서 완전히 틀렸을 수 있습니다 (그리고 희망합니다), 이런 방식으로 인증하는 것이 신뢰할 수 있는지 여부를 설명 할 수 있습니까? 아니면 좋은 대안이 무엇인지 설명 할 수 있습니까? 전반적으로 저는 사용자가 자주 재 인증을 강요하지 않고 안전하게 API 액세스에 ‘로그인’상태를 유지할 수있는 방법을 찾고 있습니다.
답변
token_authenticatable
타이밍 공격에 취약합니다 . 이 블로그 게시물 에 잘 설명되어 있습니다. 이러한 공격은 token_authenticatable
Devise 3.1에서 제거 된 이유 였습니다. 자세한 내용은 plataformatec 블로그 게시물 을 참조하십시오.
가장 안전한 토큰 인증 메커니즘을 갖기 위해 토큰은 다음을 수행합니다.
-
HTTPS를 통해 전송되어야합니다.
-
임의의 암호화 강도 여야합니다.
-
안전하게 비교되어야합니다.
-
데이터베이스에 직접 저장하면 안됩니다. 토큰의 해시 만 저장할 수 있습니다. (토큰 = 암호를 기억하십시오. 암호는 db에 일반 텍스트로 저장하지 않습니까?)
-
일부 논리에 따라 만료되어야합니다.
유용성을 위해 이러한 점 중 일부를 앞두고 있다면 가능한 한 안전하지 않은 메커니즘으로 끝날 것입니다. 그렇게 간단합니다. 처음 세 가지 요구 사항을 충족하고 데이터베이스에 대한 액세스를 제한한다면 충분히 안전해야합니다.
내 대답 확장 및 설명 :
-
HTTPS를 사용 합니다. 이것은 스니퍼를 다루기 때문에 확실히 가장 중요한 포인트입니다.
HTTPS를 사용하지 않으면 많은 문제가 발생할 수 있습니다. 예를 들면 :
-
사용자의 자격 증명 (사용자 이름 / 이메일 / 비밀번호)을 안전하게 전송하려면 다이제스트 인증을 사용해야하지만 솔트 된 해시가 무차별 적으로 강제 될 수 있기 때문에 요즘은이를 차단하지 않습니다 .
-
Rails 3에서 쿠키는 Base64 인코딩으로 만 가려져 있으므로 상당히 쉽게 공개 할 수 있습니다. 자세한 내용은 Rails 세션 쿠키 디코딩 을 참조하세요.
하지만 Rails 4 이후로 쿠키 저장소는 암호화되어 데이터가 디지털로 확인되고 공격자가 읽을 수 없습니다. 쿠키는
secret_key_base
유출되지 않는 한 안전해야합니다 .
-
-
다음을 사용하여 토큰을 생성하십시오.
SecureRandom.hex
Ruby 2.5 이상을 사용하는 경우에만.sysrandom
오래된 Ruby를 사용하는 경우 보석 .
이것이 왜 필요한지에 대한 설명은
sysrandom
의 README 및 블로그 게시물 How to Generate Secure Random Numbers in Various Programming Languages를 참조하십시오 . -
사용자의 ID, 이메일 또는 기타 속성을 사용하여 사용자 레코드를 찾으십시오. 그런 다음 해당 사용자의 토큰을 요청의 토큰과
Devise.secure_compare(user.auth_token, params[:auth_token]
. Rails 4.2.1+를 사용하는 경우ActiveSupport::SecurityUtils.secure_compare
.마십시오 하지 같은 레일 파인더와 사용자 레코드를 찾을 수 있습니다
User.find_by(auth_token: params[:auth_token])
. 이것은 타이밍 공격에 취약합니다! -
사용자 당 동시에 여러 응용 프로그램 / 세션을 가질 경우 두 가지 옵션이 있습니다.
-
암호화되지 않은 토큰을 데이터베이스에 저장하여 장치간에 공유 할 수 있습니다. 이것은 나쁜 습관이지만 UX라는 이름으로 할 수 있다고 생각합니다 (그리고 DB 액세스 권한으로 직원을 신뢰한다면).
-
현재 세션을 허용하려는만큼 사용자 당 암호화 된 토큰을 저장합니다. 따라서 2 개의 서로 다른 장치에서 2 개의 세션을 허용하려면 데이터베이스에 2 개의 개별 토큰 해시를 유지하십시오. 이 옵션은 구현하기가 조금 덜 간단하지만 확실히 더 안전합니다. 또한 사용자에게 토큰을 취소하여 특정 장치에서 현재 활성 세션을 종료 할 수있는 옵션을 제공 할 수 있다는 장점도 있습니다 ( GitHub 및 Facebook처럼).
-
-
토큰이 만료되도록하는 메커니즘이 있어야합니다. 이 메커니즘을 구현할 때 UX와 보안 간의 균형을 고려해야합니다.
Google은 6 개월 동안 사용하지 않은 토큰을 만료 시킵니다.
Facebook은 토큰이 2 개월 동안 사용되지 않은 경우 만료됩니다 .
Facebook의 SDK를 사용하는 네이티브 모바일 앱은 약 60 일 동안 유효한 장기 액세스 토큰을 받게됩니다. 이 토큰은 앱을 사용하는 사람이 Facebook 서버에 요청하면 하루에 한 번 새로 고침됩니다. 요청이 없으면 토큰은 약 60 일 후에 만료되며 사용자는 새 토큰을 얻기 위해 다시 로그인 흐름을 거쳐야합니다.
-
암호화 된 쿠키 저장소를 사용하려면 Rails 4로 업그레이드하세요. 할 수없는 경우 여기에 제안 된대로 쿠키 저장소를 직접 암호화 하십시오 . 암호화 된 쿠키 저장소에 인증 토큰을 저장하는 데 전혀 문제가 없습니다.
예를 들어, 데이터베이스의 토큰 하위 집합 또는 모든 단일 토큰을 재설정하는 레이크 작업과 같은 비상 계획도 있어야합니다.
시작하려면 Devise로 토큰 인증을 구현하는 방법에 대한 이 요점 (Devise 작성자 중 한 사람)을 확인할 수 있습니다. 마지막으로, API 보안에 대한 Railscast 가 도움이 될 것입니다.
답변
프로젝트의 README에 따르면 devise_token_auth gem은이 StackOverflow 게시물에서 영감을 얻었습니다 : https://github.com/lynndylanhurley/devise_token_auth
답변
API와 함께 rails4 를 사용해 볼 수 있으며 , 더 많은 보안을 제공하고 devise 3.1.0rc를 사용합니다.
-
Rails 4.0에서는 몇 가지 기능이 gem으로 추출되었습니다.
- ActiveRecord :: SessionStore
- 액션 캐싱
- 페이지 캐싱
- 중첩 템플릿의 자동 종속성 관리를 통해 키 기반 만료를 통한 러시아 인형 캐싱.
http://blog.envylabs.com/post/41711428227/rails-4-security-for-session-cookies
-
Devise 3.1.0.rc는 Rails 3.2와 Rails 4.0에서 실행됩니다.
http://blog.plataformatec.com.br/2013/08/devise-3-1-now-with-more-secure-defaults/ -
Devise는
TokenAuthenticatable
3.1.0rc에서 더 이상 사용되지 않지만 보안 문제에 대한 자체TokenAuthenticatable
방법을 구축 할 수 있습니다 . 더 안정적이고 안전합니다.
토큰, 세션 스토어의 경우 http://ruby.railstutorial.org/chapters/sign-in-sign-out 및 http://blog.bigbinary.com/2013/03/19/cookies-on-rails를 통해 이동할 수 있습니다. .html 을 참조하세요.
마지막으로 보안 강화를 위해 이러한 종류의 암호화 및 암호 해독 ” 저장된 암호화 된 데이터를 해독 할 수 없음 “을 거쳐야합니다 .