Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Authentication Security – RUBYSPB
Search
Sergey Nartimov
September 21, 2013
Programming
210
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Authentication Security – RUBYSPB
Sergey Nartimov
September 21, 2013
Transcript
50 slides
Безопасность аутентификации веб-приложений Сергей Нартымов Brainspec https://github.com/lest twitter: @just_lest
None
Хэш с солью
None
Хэш с солью create_table :users do |t| t.string :name t.string
:salt t.string :hashed_password end
Хэш с солью def self.encrypted_password(password, salt) string_to_hash = password +
"wibble" + salt Digest::SHA1.hexdigest(string_to_hash) end def create_new_salt self.salt = self.object_id.to_s + rand.to_s end
Хэш с солью def password=(pwd) @password = pwd return if
pwd.blank? create_new_salt self.hashed_password = User.encrypted_password(self.password, self.salt) end
Хэш с солью def self.authenticate(name, password) user = self.find_by_name(name) if
user expected_password = encrypted_password(password, user.salt) if user.hashed_password != expected_password user = nil end end user end
has_secure_password
create_table :users do |t| t.string :name t.string :password_digest end class
User < ActiveRecord::Base has_secure_password end
user = User.new(name: "david") user.password = "mUc3m00RsqyRe" user.password_digest # =>
"$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/ xeUVtMTYqwIvYY76EW5GUqDiP4." user.save user.authenticate("notright") # => false user.authenticate("mUc3m00RsqyRe") # => user
bcrypt
bcrypt $2a$10$vI8aWBnW3fID.ZQ4/z идентификатор алгоритма
bcrypt $2a$10$vI8aWBnW3fID.ZQ4/zo1G сложность
bcrypt $2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps соль
bcrypt o1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa
bcrypt def password=(unencrypted_password) unless unencrypted_password.blank? @password = unencrypted_password cost =
ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine::DEFAULT_COST self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost) end end def authenticate(unencrypted_password) BCrypt::Password.new(password_digest) == unencrypted_password && self end
bcrypt def password=(unencrypted_password) unless unencrypted_password.blank? @password = unencrypted_password cost =
ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine::DEFAULT_COST self.password_digest = BCrypt::Password.create(unencrypted_password, cost: cost) end end def authenticate(unencrypted_password) BCrypt::Password.new(password_digest) == unencrypted_password && self end
bcrypt
PBKDF2 scrypt bcrypt
PBKDF2 scrypt bcrypt
Инвалидация сессии
Инвалидация сессии user = User.authenticate(params[:name], params[:password]) if user session[:user_id] =
user.id redirect_to(:action => "index") else flash.now[:notice] = "Invalid user/password combination" end
Инвалидация сессии • хранить в сессии данные, которые изменяются при
изменении пароля • например, соль пароля (так делает devise)
Инвалидация сессии def serialize_into_session(record) [record.to_key, record.authenticatable_salt] end def authenticatable_salt encrypted_password[0,29]
if encrypted_password end
Блокировка доступа
Блокировка доступа • для пользователя • для IP-адреса
Блокировка доступа • CAPTCHA • разблокировка по ссылке из письма
Запомнить меня
Запомнить меня • добавляем токен и время • храним токен
в HttpOnly cookie
Запомнить меня def remember_me!(extend_period=false) self.remember_token = self.class.remember_token if generate_remember_token? self.remember_created_at
= Time.now.utc if generate_remember_timestamp?(extend_period) save(:validate => false) if self.changed? end
Запомнить меня cookies.signed[remember_key(resource, scope)] = remember_cookie_values(resource) def remember_cookie_values(resource) options =
{ :httponly => true } # ... options.merge!( :value => resource.class.serialize_into_cookie(resource), :expires => resource.remember_expires_at ) end
Перебор пользователей
• Неверный адрес e-mail или пароль. • Если ваш адрес
e-mail есть в нашей базе данных, то в течение нескольких минут вы получите письмо с инструкциями по восстановлению вашего пароля.
Тайминговые атаки
Тайминговые атаки def authenticate! resource = valid_password? && mapping.to.find_for_database_authentication(authentication_hash) return
fail(:not_found_in_database) unless resource if validate(resource){ resource.valid_password?(password) } resource.after_database_authentication success!(resource) end end
Тайминговые атаки user = User.last Benchmark.realtime { user.valid_password?('lolwut') } #
=> 0.321346
Восстановление пароля • не стоит генерировать пароль и присылать его
на почту • лучше генерировать токен и отправлять ссылку, по которой можно задать новый пароль
Сложность пароля
Сложность пароля validates :password, length: { minimum: 5, maximum: 20
}
SSL
SSL startssl.com
Двухэтапная аутентификация
Google Двухэтапная аутентификация
Google Facebook Двухэтапная аутентификация
Google Facebook Dropbox Двухэтапная аутентификация
Google Facebook AWS Dropbox Двухэтапная аутентификация
Google Facebook AWS Dropbox GitHub Двухэтапная аутентификация
Open Web Application Security Project • https://www.owasp.org/ • https://www.owasp.org/index.php/ Cheat_Sheets
Спасибо https://github.com/lest twitter: @just_lest Сергей Нартымов Brainspec
More Decks by Sergey Nartimov
See All by Sergey Nartimov
PubSub at Rails
lest
0
160
Rails in production - RubyConfBY 22 Mar 2015
lest
1
170
Sequel - BRUG 21 Feb 2015
lest
0
110
Elixir – Belarus Ruby User Group 25 Jan 2014
lest
3
680
Geospatial applications on Rails
lest
8
460
Design patterns – Belarus Ruby on Rails User Group 23 Feb 2013
lest
8
680
Ruby Stdlib – Minsk.rb October 2012
lest
10
440
Background jobs with realtime results – RailsClub'Moscow 2012
lest
5
240
Other Decks in Programming
See All in Programming
はじめてのPLATEAU
nokonoko1203
1
650
そのデザイントークン、Flutterでも同じ見た目になりますか?
nakamizu
0
340
flutter_test のその先へ — Flutter アプリの LLM 機能に「評価」という品質保証を
kosukesaigusa
0
200
Getting Started with Vibe Coding
miccheng
0
220
Web Framework Benchmark Battle 2026, Any%
a_matsuda
3
3.2k
AI時代のIaC入門 〜なぜインフラをコードで管理したいのか?〜 / Introduction to IaC in the AI Era
akihisaikeda
6
1.5k
Будущее локальных LLM – Алексей Голобурдин, PythoNN
sobolevn
0
120
Performance Optimization With LLMs
xleitix
0
260
조합이폭발하는디자인시스템이걸눈으로도테스트하라고요
giljongyu
0
750
AIが実装を担う時代の「技術設計」と「チームマネジメント」
kamina_zzz
2
260
PyConTW 2026 - AI Coding 不只是工具升級, 區域醫院醫療資訊系統協作開發與資訊團隊轉型實踐
cclai999
0
250
우리의 Nitro Modules는 당신의 Turbo Modules보다 아름답다
l2hyunwoo
0
260
Featured
See All Featured
Rails Girls Zürich Keynote
gr2m
96
14k
Impact Scores and Hybrid Strategies: The future of link building
tamaranovitovic
0
480
Building Experiences: Design Systems, User Experience, and Full Site Editing
marktimemedia
1
660
Practical Tips for Bootstrapping Information Extraction Pipelines
honnibal
25
2.2k
A Modern Web Designer's Workflow
chriscoyier
699
190k
Building a A Zero-Code AI SEO Workflow
portentint
PRO
0
830
Building an army of robots
kneath
307
47k
Building Adaptive Systems
keathley
44
3.3k
The B2B funnel & how to create a winning content strategy
katarinadahlin
PRO
1
610
Technical Leadership for Architectural Decision Making
baasie
4
640
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
63
48k
So, you think you're a good person
axbom
PRO
2
2.3k