Cam*_*ron 13 session ruby-on-rails
在我们的Rails应用程序中,我们protect_from_forgery用来防止CSRF.
然而,我们发现,如果用户访问登录页面,然后在应用程序会话到期时间(比如说15分钟)的时间内去喝茶.登录只是重定向回登录页面,无论是否成功凭据(根据环境,我们得到错误InvalidAuthenticityToken.)尝试再次登录工作正常.只有当用户在页面上的时间超过会话时间时才会失败.
我们认为这很奇怪,因为我们尚未登录...所以会话即将到期?并且肯定会在登录时创建新会话,即使已创建并已过期.事实证明(阅读本文后:https://nvisium.com/blog/2014/09/10/understanding-protectfromforgery/)Rails中的CSRF保护实际上使用会话来检查authenticity_token是否有效.因此,基本上会话在会话到期时到期(取决于session_store设置),并且如果不再刷新页面,则无法登录.
我们解决了这个问题:skip_before_action :verify_authenticity_token, only: [:create]在我们这里,SessionsController但现在这意味着我们的登录表单不再受到保护.
有什么其他选择来解决这个问题?或者我们使用的解决方案并不像我们想象的那样不安全?谷歌搜索显示这行代码使用了很多次,但肯定这是一个坏主意?
我们的另一个解决方案是允许Exception发生,但是优雅地处理它:
rescue_from ActionController::InvalidAuthenticityToken do
@exception = exception.message
render 'errors/500', :status => 500, :layout => 'other'
end
Run Code Online (Sandbox Code Playgroud)
虽然仍然讨厌用户坐在登录页面上的时间超过会话超时(在这种情况下为15分钟)会导致错误!
我们提出的另一个解决方案是将session_store设置为永久,然后手动过期登录会话,如下所示:
before_action :session_timeout, if: :current_user
def session_timeout
session[:last_seen_at] ||= Time.now
if session[:last_seen_at] < 15.minutes.ago
reset_session
else
session[:last_seen_at] = Time.now
end
end
Run Code Online (Sandbox Code Playgroud)
什么会话即将到期?
有问题的会话是Rails会话(参见Ruby on Rails安全指南中的什么是会话?),这是一个轻量级的数据存储抽象,它在HTTP请求中保持任意状态(默认情况下,在加密cookie中,其他会话存储)也可以配置实现).会话状态可以包括经过身份验证的用户ID,但也可以用于其他目的.
在这种情况下,会话不会用于用户身份验证,而是存储临时"真实性令牌"作为Rails安全功能的一部分,以保护您的网站免受跨 POST(或其他非)的跨站点请求伪造(CSRF)攻击-GET)请求.
在Rails的API文档详细描述了此功能:
通过在应用程序的呈现HTML中包含令牌,可以保护控制器操作免受跨站请求伪造(CSRF)攻击.此令牌作为随机字符串存储在会话中,攻击者无权访问该会话.当请求到达您的应用程序时,Rails会在会话中使用令牌验证收到的令牌.
另请参阅Ruby on Rails安全指南中的跨站点请求伪造部分,以更全面地了解CSRF攻击是什么,以及基于会话的真实性 - 令牌验证如何防御它.
有什么其他选择来解决这个问题?
增加Rails会话到期时间的持续时间(例如,通过增加expire_after传递给cookie_store初始化程序的选项的持续时间,或完全删除选项以使会话永不过期).
使用Devise的:timeoutable模块,而不是使用会话cookie过期来使登录的会话过期:
devise :timeoutable, timeout_in: 15.minutes
Run Code Online (Sandbox Code Playgroud)或者我们使用的解决方案并不像我们想象的那样不安全?
配置Rails以跳过verify_authenticity_token回调会禁用该特定控制器操作的CSRF保护,这会使操作容易受到CSRF攻击.
那么,为了重新解释你的问题,是否只为那些在任何重要/有意义的意义上SessionsController#create仍然不安全的行为禁用CSRF保护?虽然这取决于你的申请,但总的来说是的,我相信.
考虑这种情况:
CSRF攻击SessionsController#create将允许攻击者恶意指示受害者的浏览器登录攻击者控制下的用户帐户.下次受害者访问您的网站时(例如,当被攻击者重定向时),他们的浏览器仍然可以登录到攻击者控制的帐户.受害者可能会在不知情的情况下提交敏感的个人数据或在您的网站上执行敏感操作,攻击者可以阅读这些操作.
虽然这种情况可能会比可能发生,如果CSRF保护了其他更敏感的/破坏性的控制器动作禁止什么不太明显的危险性,但仍暴露出不够,我认为这是足够不安全推荐潜在用户/数据隐私问题的反对禁用默认保护.