Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Authentication Security – RUBYSPB

Authentication Security – RUBYSPB

Sergey Nartimov

September 21, 2013
Tweet

More Decks by Sergey Nartimov

Other Decks in Programming

Transcript

  1. Хэш с солью 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
  2. Хэш с солью def password=(pwd) @password = pwd return if

    pwd.blank? create_new_salt self.hashed_password = User.encrypted_password(self.password, self.salt) end
  3. Хэш с солью 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
  4. create_table :users do |t| t.string :name t.string :password_digest end class

    User < ActiveRecord::Base has_secure_password end
  5. 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
  6. 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
  7. 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
  8. Инвалидация сессии 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
  9. Инвалидация сессии • хранить в сессии данные, которые изменяются при

    изменении пароля • например, соль пароля (так делает devise)
  10. Запомнить меня 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
  11. • Неверный адрес e-mail или пароль. • Если ваш адрес

    e-mail есть в нашей базе данных, то в течение нескольких минут вы получите письмо с инструкциями по восстановлению вашего пароля.
  12. Тайминговые атаки 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
  13. Восстановление пароля • не стоит генерировать пароль и присылать его

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