我正在使用旧版Rails应用程序,正在尝试清理一些CSRF漏洞。如果我从表单中删除了隐藏的CSRF字段,我仍然可以成功提交表单。
唯一不正确的指示是日志中的警告:WARNING: Can't verify CSRF token authenticity
。
[在某些页面上,protect_from_forgery
将捕获请求,并且如果没有csrf令牌,但它的命中和丢失取决于页面,则应用程序将崩溃:例如。登录页面没有令牌即可工作,但更新用户页面则无法。
我已经尝试针对Marc Gauthier提出一个自定义策略(由protect_from_forgery
建议),例如:
protect_from_forgery with: :MyStrategy
class MyStrategy
byebug
def initialize(controller)
@contriller = controller
end
def handle_unverified_request
puts "HELLO!"
Rails.logger.warn [
"handle_unverified_request",
"#{@controller.controller_name}-#{@controller.action_name}"
].join(" - ")
end
end
[启动应用程序时似乎没有执行任何操作,byebug
调用将暂停,但我从没收到puts
消息或错误日志。
我也尝试了诸如with: :exception
之类的常规策略,但没有任何变化,某些页面有效,有些页面无效,但是它们是一致的。
通常,保护登录用户的会话免受CSRF的侵害很重要,因此在许多应用中,习惯上应禁用登录/注销保护,以防止合法用户出错。在大多数情况下,如果会话将要终止/重置,RF不会造成太大的伤害。
寻找skip_before_action :verify_authenticity_token
禁用protect_from_forgery
正在安装的操作
检查您的测试方法-隐藏表单字段并非总是必需的,因为Rails还对Ajax表单使用X-CSRF-Token
标头。要正确测试伪造保护-进行实际的伪造尝试,例如使用curl
。
检查config.action_controller.allow_forgery_protection
是否未禁用以进行开发/生产,并且控制器或其祖先的allow_forgery_protection
没有超载,并且针对所请求的请求返回false
。可能性很小,但应用程序的伪造保护其他部分可能会被覆盖,请参阅request_forgery_protection.rb
PS。在这种情况下,类上下文中的byebug
不是很有用,更可见的方式是在raise "Hello CSRF"
]中的handle_unverified_request