Devise의 token_authenticatable은 안전한가요?


79

저는 Rails API 로 간단한 API를 구축하고 있으며 여기에서 올바른 방향으로 가고 있는지 확인하고 싶습니다. 로그인을 처리하기 위해 devise를 사용하고 token_authenticatable있으며 각 요청과 함께 보내야하는 API 키를 생성하는 Devise의 옵션 을 사용하기로 결정했습니다 .

API를 백본 / 마리오네트 프런트 엔드와 페어링하고 있으며 일반적으로 세션을 어떻게 처리해야하는지 궁금합니다. 내 첫 번째 생각은 로컬 저장소 또는 쿠키에 api 키를 저장하고 페이지로드시 검색하는 것이었지만 보안 관점에서 api 키를 저장하는 것에 대한 무언가가 나를 괴롭 혔습니다. 로컬 저장소 / 쿠키를 찾거나 전달되는 요청을 스니핑하여 API 키를 가져 와서 해당 사용자를 무기한으로 가장하는 데 사용하는 것이 쉽지 않을까요? 현재는 로그인 할 때마다 api 키를 재설정하고 있지만 그럴 경우에도 자주 보입니다. 어떤 기기에서든 로그인 할 때마다 다른 기기에서 모두 로그 아웃된다는 의미입니다. 이는 일종의 고통입니다. 이 재설정을 취소 할 수 있다면 사용성 관점에서 개선 될 것 같습니다.

나는 여기에서 완전히 틀렸을 수 있습니다 (그리고 희망합니다), 이런 방식으로 인증하는 것이 신뢰할 수 있는지 여부를 설명 할 수 있습니까? 아니면 좋은 대안이 무엇인지 설명 할 수 있습니까? 전반적으로 저는 사용자가 자주 재 인증을 강요하지 않고 안전하게 API 액세스에 '로그인'상태를 유지할 수있는 방법을 찾고 있습니다.

답변:


190

token_authenticatable타이밍 공격에 취약합니다 . 이 블로그 게시물 에 잘 설명되어 있습니다. 이러한 공격은 token_authenticatableDevise 3.1에서 제거 된 이유 였습니다. 자세한 내용은 plataformatec 블로그 게시물 을 참조하십시오.

가장 안전한 토큰 인증 메커니즘을 갖기 위해 토큰은 다음을 수행합니다.

  1. HTTPS를 통해 전송되어야합니다.

  2. 임의의 암호화 강도 여야합니다.

  3. 안전하게 비교되어야합니다.

  4. 데이터베이스에 직접 저장하면 안됩니다. 토큰의 해시 만 저장할 수 있습니다. (토큰 = 암호를 기억하십시오. 암호는 db에 일반 텍스트로 저장하지 않습니까?)

  5. 일부 논리에 따라 만료되어야합니다.

유용성을 위해 이러한 점 중 일부를 앞두고 있다면 가능한 한 안전하지 않은 메커니즘으로 끝날 것입니다. 그렇게 간단합니다. 처음 세 가지 요구 사항을 충족하고 데이터베이스에 대한 액세스를 제한한다면 충분히 안전해야합니다.

내 대답 확장 및 설명 :

  1. HTTPS를 사용 합니다. 이것은 스니퍼를 다루기 때문에 확실히 가장 중요한 포인트입니다.

    HTTPS를 사용하지 않으면 많은 문제가 발생할 수 있습니다. 예를 들면 :

  2. 다음을 사용하여 토큰을 생성하십시오.

    이것이 왜 필요한지에 대한 설명은 sysrandom의 README 및 블로그 게시물 How to Generate Secure Random Numbers in Various Programming Languages를 참조하십시오 .

  3. 사용자의 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]). 이것은 타이밍 공격에 취약합니다!

  4. 사용자 당 동시에 여러 응용 프로그램 / 세션을 가질 경우 두 가지 옵션이 있습니다.

    • 암호화되지 않은 토큰을 데이터베이스에 저장하여 장치간에 공유 할 수 있습니다. 이것은 나쁜 습관이지만 UX라는 이름으로 할 수 있다고 생각합니다 (그리고 DB 액세스 권한으로 직원을 신뢰한다면).

    • 현재 세션을 허용하려는만큼 사용자 당 암호화 된 토큰을 저장합니다. 따라서 2 개의 서로 다른 장치에서 2 개의 세션을 허용하려면 데이터베이스에 2 개의 개별 토큰 해시를 유지하십시오. 이 옵션은 구현하기가 조금 덜 간단하지만 확실히 더 안전합니다. 또한 사용자에게 토큰을 취소하여 특정 장치에서 현재 활성 세션을 종료 할 수있는 옵션을 제공 할 수 있다는 장점도 있습니다 ( GitHub 및 Facebook처럼).

  5. 토큰이 만료되도록하는 메커니즘이 있어야합니다. 이 메커니즘을 구현할 때 UX와 보안 간의 균형을 고려해야합니다.

    Google은 6 개월 동안 사용하지 않은 토큰을 만료 시킵니다.

    Facebook은 토큰이 2 개월 동안 사용되지 않은 경우 만료됩니다 .

    Facebook의 SDK를 사용하는 네이티브 모바일 앱은 약 60 일 동안 유효한 장기 액세스 토큰을 받게됩니다. 이 토큰은 앱을 사용하는 사람이 Facebook 서버에 요청하면 하루에 한 번 새로 고침됩니다. 요청이 없으면 토큰은 약 60 일 후에 만료되며 사용자는 새 토큰을 얻기 위해 다시 로그인 흐름을 거쳐야합니다.

  6. 암호화 된 쿠키 저장소를 사용하려면 Rails 4로 업그레이드하세요. 할 수없는 경우 여기에 제안 된대로 쿠키 저장소를 직접 암호화 하십시오 . 암호화 된 쿠키 저장소에 인증 토큰을 저장하는 데 전혀 문제가 없습니다.

예를 들어, 데이터베이스의 토큰 하위 집합 또는 모든 단일 토큰을 재설정하는 레이크 작업과 같은 비상 계획도 있어야합니다.

시작하려면 Devise로 토큰 인증을 구현하는 방법에 대한 이 요점 (Devise 작성자 중 한 사람)을 확인할 수 있습니다. 마지막으로, API 보안에 대한 Railscast 가 도움이 될 것입니다.


대단합니다, 이것은 많은 도움이됩니다-감사합니다! 이것은 거의 확실히 정답을 얻을 것입니다. 당신이 핸들 API 인증하는 가장 좋은 방법에 (특히)이 당신의 의견 / 권고에 추가하는 경우 현상금은 당신입니다 :)
제프 에스

1
두 방법 모두 임의의 문자열을 urlsafe_base64생성하지만 URL에 안전한 문자열을 생성합니다. 모두 이름에 있습니다. 당신이 당신의 URL에 토큰을 사용하고자하지 않는 한 ( 하는 당신은 안 사용) hex.
Ashitaka

2
토큰! = 암호. 토큰을 일반 텍스트로 저장하는 것은 잘못된 것이 아닙니다. 일반 텍스트로 암호를 저장하는 문제는 암호를 다른 곳에서 사용할 수 있다는 것입니다. 토큰에는 해당되지 않아야합니다.
fatfrog

2
@fatfrog 번호 토큰 == 암호. 해커 나 불만을 품은 직원이 귀하의 데이터베이스에 액세스 할 수있는 경우 그는 특정 사용자 또는 관리자로 인증 할 수 없어야합니다.
Ashitaka

1
동의하지 않습니다. 해커 나 불만을 품은 직원이 데이터베이스에 액세스 할 수 있다면 토큰이 마지막으로 걱정할 필요가 있습니다. 그들은 이미 귀하의 데이터를 가지고 있습니다.
fatfrog


3

API와 함께 rails4 를 사용해 볼 수 있으며 , 더 많은 보안을 제공하고 devise 3.1.0rc를 사용합니다.

토큰, 세션 스토어의 경우 http://ruby.railstutorial.org/chapters/sign-in-sign-outhttp://blog.bigbinary.com/2013/03/19/cookies-on-rails를 통해 이동할 수 있습니다. .html 을 참조하세요.

마지막으로 보안 강화를 위해 이러한 종류의 암호화 및 암호 해독 " 저장된 암호화 된 데이터를 해독 할 수 없음 "을 거쳐야합니다 .


누구든지 사용자 정의 빌드 대안이 있습니까?
다니엘 모리스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.