Authentication security

50
Безопасность аутентификации веб-приложений Сергей Нартымов Brainspec https://github.com/lest twitter: @just_lest

description

Сергей Нартымов (Sortware Engineer в Brainspec, Rails, Rubinius, Elixir contributor) Доклад: Безопасность аутентификации веб-приложений.

Transcript of Authentication security

Page 1: Authentication security

Безопасность аутентификациивеб-приложений

Сергей НартымовBrainspec

https://github.com/lesttwitter: @just_lest

Page 2: Authentication security
Page 3: Authentication security

Хэш с солью

Page 4: Authentication security
Page 5: Authentication security

Хэш с солью

create_table :users do |t| t.string :name t.string :salt t.string :hashed_passwordend

Page 6: Authentication security

Хэш с солью

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_send

Page 7: Authentication security

Хэш с солью

def password=(pwd) @password = pwd return if pwd.blank? create_new_salt self.hashed_password = User.encrypted_password(self.password, self.salt)end

Page 8: Authentication security

Хэш с солью

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 userend

Page 9: Authentication security

has_secure_password

Page 10: Authentication security

create_table :users do |t| t.string :name t.string :password_digestend

class User < ActiveRecord::Base has_secure_passwordend

Page 11: Authentication security

user = User.new(name: "david")user.password = "mUc3m00RsqyRe"user.password_digest# => "$2a$10$4LEA7r4YmNHtvlAvHhsYAeZmk/xeUVtMTYqwIvYY76EW5GUqDiP4."

user.save

user.authenticate("notright") # => falseuser.authenticate("mUc3m00RsqyRe") # => user

Page 12: Authentication security

bcrypt

Page 13: Authentication security

bcrypt

$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

идентификатор алгоритма

Page 14: Authentication security

bcrypt

$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

сложность

Page 15: Authentication security

bcrypt

$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

соль

Page 16: Authentication security

bcrypt

$2a$10$vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

Page 17: Authentication security

bcryptdef 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) endend

def authenticate(unencrypted_password) BCrypt::Password.new(password_digest) == unencrypted_password && selfend

Page 18: Authentication security

bcryptdef 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) endend

def authenticate(unencrypted_password) BCrypt::Password.new(password_digest) == unencrypted_password && selfend

Page 19: Authentication security

bcrypt

Page 20: Authentication security

PBKDF2

scryptbcrypt

Page 21: Authentication security

PBKDF2

scryptbcrypt

Page 22: Authentication security

Перебор пользователей

Page 23: Authentication security

• Неверный адрес e-mail или пароль.

• Если ваш адрес e-mail есть в нашей базе данных, то в течение нескольких минут вы получите письмо с инструкциями по восстановлению вашего пароля.

Page 24: Authentication security

Тайминговые атаки

Page 25: Authentication security

Тайминговые атаки

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) endend

Page 26: Authentication security

Тайминговые атаки

user = User.last

Benchmark.realtime { user.valid_password?('lolwut') }# => 0.321346

Page 27: Authentication security

Блокировка доступа

Page 28: Authentication security

Блокировка доступа

• для пользователя• для IP-адреса

Page 29: Authentication security

Блокировка доступа

• CAPTCHA

• разблокировка по ссылке из письма

Page 30: Authentication security

Инвалидация сессии

Page 31: Authentication security

Инвалидация сессии

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

Page 32: Authentication security

Инвалидация сессии

• хранить в сессии данные, которые изменяются при изменении пароля

• например, соль пароля (так делает devise)

Page 33: Authentication security

Инвалидация сессии

def serialize_into_session(record) [record.to_key, record.authenticatable_salt]end

def authenticatable_salt encrypted_password[0,29] if encrypted_passwordend

Page 34: Authentication security

Запомнить меня

Page 35: Authentication security

Запомнить меня

• добавляем токен и время

• храним токен в HttpOnly cookie

Page 36: Authentication security

Запомнить меня

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

Page 37: Authentication security

Запомнить меня

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

Page 38: Authentication security

Восстановление пароля

• не стоит генерировать пароль и присылать его на почту

• лучше генерировать токен и отправлять ссылку, по которой можно задать новый пароль

Page 39: Authentication security

Сложность пароля

Page 40: Authentication security

Сложность пароля

validates :password, length: { minimum: 5, maximum: 20 }

Page 41: Authentication security

SSL

Page 42: Authentication security

SSL

startssl.com

Page 43: Authentication security

Двухэтапная аутентификация

Page 44: Authentication security

Google

Двухэтапная аутентификация

Page 45: Authentication security

Google

Facebook

Двухэтапная аутентификация

Page 46: Authentication security

Google

Facebook

Dropbox

Двухэтапная аутентификация

Page 47: Authentication security

Google

Facebook

AWS

Dropbox

Двухэтапная аутентификация

Page 48: Authentication security

Google

Facebook

AWS

Dropbox

GitHub

Двухэтапная аутентификация

Page 50: Authentication security

Спасибо

https://github.com/lesttwitter: @just_lest

Сергей НартымовBrainspec