Program Club

Devise의 token_authenticatable은 안전한가요?

proclub 2020. 10. 15. 22:00
반응형

Devise의 token_authenticatable은 안전한가요?


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

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

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


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로 업그레이드하세요. 할 수없는 경우 여기에 제안 된대로 쿠키 저장소를 직접 암호화 하십시오 . 암호화 된 쿠키 저장소에 인증 토큰을 저장하는 데 전혀 문제가 없습니다.

You should also have a contingency plan, for example, a rake task to reset a subset of tokens or every single token in the database.

To get you started, you could check out this gist (by one of the authors of Devise) on how to implement token authentication with Devise. Finally, the Railscast on securing an API should be helpful.


According to the project's README, the devise_token_auth gem was inspired by this StackOverflow post: https://github.com/lynndylanhurley/devise_token_auth


You can try to use rails4 with your API, it's providing more security and use devise 3.1.0rc

For token, session store you can go through http://ruby.railstutorial.org/chapters/sign-in-sign-out and http://blog.bigbinary.com/2013/03/19/cookies-on-rails.html for more understable.

At last you should go through these kind of encryption and decryption "Unable to decrypt stored encrypted data" to get the more security.

참고URL : https://stackoverflow.com/questions/18605294/is-devises-token-authenticatable-secure

반응형