{"id":3598,"date":"2013-08-13T14:40:09","date_gmt":"2013-08-13T17:40:09","guid":{"rendered":"http:\/\/blog.plataformatec.com.br\/?p=3598"},"modified":"2018-09-24T14:22:49","modified_gmt":"2018-09-24T17:22:49","slug":"devise-3-1-now-with-more-secure-defaults","status":"publish","type":"post","link":"https:\/\/blog.plataformatec.com.br\/2013\/08\/devise-3-1-now-with-more-secure-defaults\/","title":{"rendered":"Devise 3.1: Now with more secure defaults"},"content":{"rendered":"

We are glad to announce that Devise 3.1.0.rc is out. On this version, we have focused on some security enhancements regarding our defaults and the deprecation of TokenAuthenticatable<\/code>. This blog post explains the rationale behind those changes and how to upgrade.<\/p>\n

Devise 3.1.0.rc runs on both Rails 3.2 and Rails 4.0. There is a TL;DR for upgrading at the end of this post.<\/p>\n

Note:<\/strong> We have yanked 3.1.0.rc and released to 3.1.0.rc2 which fixes some regressions. Thanks everyone for trying out the release candidates!<\/p>\n

Do not sign the user in after confirmation<\/h3>\n

In previous Devise versions, the user was automatically signed in after confirmation. This meant that anyone that could access the confirmation e-mail could sign into someone’s account by simply clicking the link.<\/p>\n

Automatically signing the user in could also be harmful in the e-mail reconfirmation workflow. Imagine that a user decides to change his e-mail address and, while doing so, he makes a typo on the new e-mail address. An e-mail will be sent to another address which, with the token in hands, would be able to sign in into that account.<\/p>\n

If the user corrects the e-mail straight away, no harm will be done. But if not, someone else could sign into that account and the user would not know that it happened.<\/p>\n

For this reason, Devise 3.1 no longer signs the user automatically in after confirmation<\/strong>. You can temporarily bring the old behavior back after upgrading by setting the following in your config\/initializers\/devise.rb<\/code>:<\/p>\n

\nconfig.allow_insecure_sign_in_after_confirmation = true\n<\/pre>\n

This option will be available only temporarily to aid migration.<\/p>\n

Thanks to Andri M\u00f6ll<\/a> for reporting this issue.<\/p>\n

Do not confirm account after password reset<\/h3>\n

In previous Devise versions, resetting the password automatically confirmed user accounts. This worked fine in previous Devise versions which confirmed the e-mail just on sign up, so the e-mail both confirmation and password reset tokens would be sent to were guaranteed to be the same. With the addition of reconfirmable, this setup change and Devise will no longer confirm the account after password reset.<\/p>\n

Thanks to Andri M\u00f6ll<\/a> for reporting this issue and working with us on a fix.<\/p>\n

CSRF on sign in<\/h3>\n

Devise’s sign in page was vulnerable to CSRF attacks when used with the rememberable feature. Note that the CSRF vulnerability is restricted only to the sign in page, allowing an attacker to sign the user in an account controlled by the attacker. This vulnerability does not allow the attacker to access or change a user account in any way.<\/p>\n

This issue is fixed on Devise 3.1.0 as well as 3.0.2 and 2.2.6. Users on previous Devise versions can patch their application by simply defining the following in their ApplicationController<\/code>:<\/p>\n

\ndef handle_unverified_request\n  super\n  Devise.mappings.each_key do |key|\n    cookies.delete \"remember_#{key}_token\"\n  end\nend\n<\/pre>\n

Thanks to Kevin Dew for reporting this issue and working with us on a fix.<\/p>\n

Store digested tokens in the database<\/h3>\n

In previous versions, Devise stored the tokens for confirmation, reset password and unlock directly in the database. This meant that somebody with read access to the database could use such tokens to sign in as someone else by, for example, resetting their password.<\/p>\n

In Devise 3.1, we store an encrypted token in the database and the actual token is sent only via e-mail to the user. This means that:<\/p>\n