Rails应用使用redirect_back回跳时如何校验用户访问权限
问题背景与现有实现
安全风险描述
我开发的应用中有一个用于创建新用户会话的方法,原有设计逻辑为:用户登录成功后通过redirect_back回跳至访问登录页前的原页面,但这套逻辑存在明确的安全问题:
- 攻击者可以手动输入自身无权限访问的页面URL发起请求
- 应用会拦截未登录请求,引导用户完成登录流程
- 即使用户使用合法凭证完成登录、且自身权限等级不足以访问手动输入的目标页面,登录成功后仍会被重定向到该越权页面
我核心想要解决的问题是:如何校验redirect_back的跳转目标,避免将用户引导至其无权限访问的页面?
当前会话创建方法代码
def create @user = authenticate(params) sign_in(@user) do |status| if status.success? redirect_back root_path else flash.now.alert = status.failure_message render :new, status: :unauthorized end end end
初步校验思路
我想确认是否可以直接获取redirect_back将要跳转的目标地址,从而实现类似如下的校验逻辑,拦截越权跳转:
if back_url.includes? "admin" redirect_to root_path end
实现方案
核心逻辑说明
你完全可以直接获取redirect_back的目标跳转地址,进而实现自定义校验逻辑。你提出的“拿到回跳地址后做权限判断”的方向是正确的,但需要注意仅靠字符串匹配路径(比如判断是否包含admin)的实现存在明显局限性,容易遗漏其他同权限等级、但路径不带对应关键词的越权场景,更稳健的实现可以参考以下要点:
- 对齐原有逻辑的默认规则:
redirect_back的本质是读取request.referer参数作为回跳目标,你可以在执行重定向前,直接从request.referer拿到完整的跳转URL,搭配root_path做兜底,和现有代码的默认回跳规则保持一致 - 复用现有权限体系做校验:不要仅靠关键词匹配做拦截,建议将回跳地址解析为对应的路由参数(控制器、action、关联资源ID),对接应用中已有的权限判断逻辑,确认当前登录用户是否真的有权访问该目标路由
- 校验不通过时直接回退到安全默认地址,跳过原有的回跳逻辑
参考实现代码
def create @user = authenticate(params) sign_in(@user) do |status| if status.success? # 按原有规则获取回跳目标,兜底为根路径 back_url = request.referer.presence || root_url # 解析回跳URL对应的路由参数 target_route = Rails.application.routes.recognize_path(back_url) # 调用应用已有的权限校验逻辑判断访问权限 if current_user_has_permission?(@user, target_route) redirect_to back_url else redirect_to root_path, alert: "您没有权限访问目标页面" end else flash.now.alert = status.failure_message render :new, status: :unauthorized end end end
如果需要快速实现最小防御能力,也可以在上述权限校验的基础上,叠加你最初想到的路径关键词判断作为补充规则,但不能仅靠关键词匹配作为唯一的校验手段。
内容的提问来源于stack exchange,提问作者Bryan Oyloe
相关产品推荐
相关产品推荐

