Чи безпечно token_authenticatable devise?


79

Я будую простий api з Rails API , і хочу переконатись, що я на правильному шляху тут. Я використовую Devise для обробки логінів і вирішив піти з Devise'stoken_authenticatable вибрати опцію , яка генерує ключ API, який потрібно надсилати з кожним запитом.

Я поєдную API з магістральною / маріонетною панеллю, і взагалі цікавлюся, як мені обробляти сеанси. Моя перша думка полягала в тому, щоб просто зберегти ключ api в локальному сховищі чи файлі cookie та отримати його під час завантаження сторінки, але щось про збереження ключа api таким чином заважало мені з точки зору безпеки. Непросто було б захопити ключ api, заглянувши в локальне сховище / файл cookie, або обнюхавши будь-який запит, який проходить, і використати його для видавання цього користувача на невизначений час? На даний момент я перезавантажую ключ api для кожного входу, але навіть це здається частим - щоразу, коли ви входите на будь-який пристрій, це означає, що ви виходите з кожного іншого, що є певною проблемою. Якби я зміг скинути це скидання, я відчуваю, що це покращиться з точки зору юзабіліті.

Я можу тут абсолютно помилятися (і сподіваюся, що помиляюся), чи може хтось пояснити, чи надійно підтверджена автентичність таким чином, і як ні, то яка хороша альтернатива? Загалом, я шукаю спосіб, яким я можу безпечно залишити користувачів «вхідними» в доступ до API, не часто примушуючи повторно авторизуватись.

Відповіді:


190

token_authenticatableвразливий до атак часу, про що дуже добре пояснено в цьому дописі в блозі . Ці атаки стали причиною token_authenticatableвидалення з Devise 3.1. Дивіться допис у блозі plataformatec отримання додаткової інформації див. .

Щоб мати найбільш безпечний механізм автентифікації маркера, маркер:

  1. Потрібно надіслати через HTTPS.

  2. Має бути випадковим, криптографічної сили.

  3. Потрібно надійно порівнювати.

  4. Не повинен зберігатися безпосередньо в базі даних. Там може зберігатися лише хеш маркера. (Пам'ятайте, лексема = пароль. Ми не зберігаємо паролі в простому тексті в базі даних, так?)

  5. Термін дії повинен закінчитися відповідно до певної логіки.

Якщо ви відмовитеся від деяких з цих пунктів на користь зручності користування, ви отримаєте механізм, який не настільки безпечний, як може бути. Це так просто. Ви повинні бути в достатній безпеці, якщо ви задовольняєте перші три вимоги та обмежуєте доступ до бази даних.

Розширюючи та пояснюючи свою відповідь:

  1. Використовуйте HTTPS . Це, безумовно, найважливіший момент, оскільки мова йде про нюхачів.

    Якщо ви не використовуєте HTTPS, то багато чого може піти не так. Наприклад:

    • Для надійної передачі облікових даних користувача (ім'я користувача / електронна пошта / пароль) вам довелося б використовувати дайджест-аутентифікацію, але це просто не вирізає цього часу, оскільки солоні хеші можуть бути грубо примусовими .

    • У Rails 3 файли cookie огорнуті кодуванням Base64, тому їх можна досить легко розкрити. Див. Декодування файлів cookie сеансу рейок отримання додаткової інформації .

      Починаючи з Rails 4, сховище файлів cookie зашифроване, тому дані одночасно перевіряються цифровим способом і не читаються зловмиснику. Файли cookie повинні бути надійними, доки ваш файл secret_key_baseне просочиться.

  2. Створіть свій маркер за допомогою:

    • SecureRandom.hex лише якщо ви використовуєте Ruby 2.5+.
    • Перлина, sysrandomякщо ви на старшій Рубі.

    Для пояснення того, чому це необхідно, я пропоную прочитати sysrandomREADME та публікацію в блозі Як створити захищені випадкові числа на різних мовах програмування .

  3. Знайдіть запис користувача, використовуючи ідентифікатор користувача, електронну адресу або інший атрибут. Потім порівняйте маркер цього користувача з маркером запиту Devise.secure_compare(user.auth_token, params[:auth_token]. Якщо ви використовуєте Rails 4.2.1+, ви також можете використовуватиActiveSupport::SecurityUtils.secure_compare .

    Ви НЕ знайдете запис користувача з шукачем Rails , як User.find_by(auth_token: params[:auth_token]). Це вразливо до атак часу!

  4. Якщо ви збираєтеся мати кілька програм / сеансів одночасно для кожного користувача, то у вас є два варіанти:

    • Зберігайте незашифрований маркер у базі даних, щоб його можна було використовувати спільно між пристроями. Це погана практика, але я думаю, ви можете це зробити від імені UX (і якщо ви довіряєте своїм співробітникам доступ до БД).

    • Зберігайте стільки зашифрованих маркерів на користувача, скільки хочете дозволити поточні сеанси. Отже, якщо ви хочете дозволити 2 сеанси на 2 різних пристроях, зберігайте 2 окремі хеші маркерів у базі даних. Цей варіант є трохи менш простим у реалізації, але він, безумовно, безпечніший. Він також має перевагу, дозволяючи вам надати своїм користувачам можливість закінчити поточні активні сеанси на певних пристроях, скасувавши їх маркери (як це роблять GitHub та Facebook).

  5. Повинен бути якийсь механізм, який змушує термін дії маркера закінчуватися. При реалізації цього механізму враховуйте компроміс між UX та безпекою.

    Google втрачає термін дії токена, якщо він не використовувався протягом шести місяців .

    Facebook втрачає термін дії токена, якщо він не використовувався протягом двох місяців :

    Рідні мобільні додатки, що використовують SDK Facebook, отримають довговічні маркери доступу, що добре приблизно 60 днів. Ці маркери оновлюватимуться раз на день, коли особа, яка використовує ваш додаток, подає запит на сервери Facebook. Якщо запитів не надсилається, термін дії маркера закінчується приблизно через 60 днів, і людині доведеться знову пройти процедуру входу, щоб отримати новий маркер.

  6. Оновіть до Rails 4, щоб скористатися своїм зашифрованим сховищем файлів cookie. Якщо ви не можете, зашифруйте магазин печива самостійно, як запропоновано тут . Зберігати маркер автентифікації в зашифрованому сховищі файлів cookie абсолютно ніяких проблем не буде.

Ви також повинні мати план дій на випадок непередбачених ситуацій, наприклад, завдання граблі для скидання підмножини маркерів або кожного окремого маркера в базі даних.

Для початку ви можете ознайомитись із цією інформацією (одного з авторів Devise) про те, як реалізувати аутентифікацію маркера за допомогою Devise. Нарешті, Railscast щодо захисту API повинен бути корисним.


Чудово, це дуже допомагає - дякую! Це майже напевно отримає правильну відповідь. Баунті за вами, якщо ви додасте до цього свою думку / рекомендацію (зокрема) щодо найкращого способу обробки автентифікації через API:)
Jeff Escalante,

1
Хоча обидва методи генерують випадковий рядок, urlsafe_base64генерує рядок, безпечний для url. Це все в назві. Якщо ви не хочете використовувати свій маркер у своїй URL-адресі ( чого не слід ), використовуйте hex.
Асітака

2
маркер! = пароль. У збереженні маркера в простому тексті немає нічого поганого. Проблема зберігання паролів у простому тексті полягає в тому, що пароль можна використовувати де-небудь ще, цього не повинно бути у випадку з вашим маркером.
fatfrog

2
@fatfrog No. Token == пароль. Якщо хакер або незадоволений співробітник має доступ до вашої бази даних, він не повинен мати змогу автентифікуватися як певний користувач або адміністратор.
Асітака

1
Я не згоден, якщо хакер або незадоволений співробітник має доступ до вашої бази даних, то токени - це останнє, про що вам потрібно турбуватися. Вони вже мають ваші дані.
fatfrog


3

Ви можете спробувати використовувати rails4 зі своїм API, це забезпечує більшу безпеку та використання devise 3.1.0rc

  • У Rails 4.0 у самоцвіти було виділено кілька функцій.

    • 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 для більш зрозумілого.

Нарешті, вам слід пройти такий тип шифрування та дешифрування " Неможливо розшифрувати збережені зашифровані дані ", щоб отримати більший рівень безпеки.


Хтось має приклад побудованої на замовлення альтернативи?
Деніел Морріс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.