Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Authentication Security – RUBYSPB
Search
Sergey Nartimov
September 21, 2013
Programming
200
2
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Authentication Security – RUBYSPB
Sergey Nartimov
September 21, 2013
More Decks by Sergey Nartimov
See All by Sergey Nartimov
PubSub at Rails
lest
0
150
Rails in production - RubyConfBY 22 Mar 2015
lest
1
170
Sequel - BRUG 21 Feb 2015
lest
0
100
Elixir – Belarus Ruby User Group 25 Jan 2014
lest
3
670
Geospatial applications on Rails
lest
8
450
Design patterns – Belarus Ruby on Rails User Group 23 Feb 2013
lest
8
670
Ruby Stdlib – Minsk.rb October 2012
lest
10
420
Background jobs with realtime results – RailsClub'Moscow 2012
lest
5
240
Other Decks in Programming
See All in Programming
Flow は今どうなっているか
mizdra
PRO
0
890
ソフトウェアエンジニアにとっての生成AI - 特性を知って使い倒す / generative ai for software enginner
kishida
7
2.3k
LoopHub - ローカルで動く GitHub で、AI と共同開発
jugyo
0
400
30年振りにコンパイラの定数整数除算を改善した
herumi
9
4.4k
まずはプロンプトガイドを読もう、話はそれからだ
kiakiraki
1
250
PHPプロジェクトの結合バランスを可視化する #php_night
kajitack
0
200
PyO3 で既存 Python 評価器を Rust core 化する ー wasm-bindgen でブラウザにも配るための設計
kdash
1
360
不幸な GC
chencmd
0
870
コンパウンドプロダクト開発のためのローカルプロセスマネージャー再発明 #layerxgo
izumin5210
0
620
Building an Out-of-Order CPU
latte72
0
640
Discordを用いたラボオートメーション関連情報収集の自動化
noguhiro2002
0
490
20260828_品質と開発生産性を両立させる、AI時代のE2Eテストの考え方
magicpod
0
130
Featured
See All Featured
[SF Ruby Conf 2025] Rails X
palkan
2
1.3k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
990
Speed Design
sergeychernyshev
33
2.1k
We Are The Robots
honzajavorek
0
330
Google's AI Overviews - The New Search
badams
0
1.6k
Building Applications with DynamoDB
mza
96
7.2k
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
370
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
230
23k
Thoughts on Productivity
jonyablonski
76
5.4k
個人開発の失敗を避けるイケてる考え方 / tips for indie hackers
panda_program
123
22k
Game over? The fight for quality and originality in the time of robots
wayneb77
1
260
Transcript
Безопасность аутентификации веб-приложений Сергей Нартымов 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