按框架
Ruby on Rails 安全 — Strong Parameters、授权与 gem 的 CVE
Rails 的默认值稳固,但事故来自运营:过于宽松的 Strong Parameters(Mass Assignment)、单薄的授权(认证≠授权)、以及已知的 gem CVE。收紧 permit、让授权显式化、监控 gem 的 CVE。以防御视角讲解,不含攻击步骤。
面向:在 Ruby on Rails 上运营应用的人。这里不讲攻击步骤——只讲如何让安全默认值持续生效,同时堵住运营开出的缺口。要看全局,请参阅 按框架的安全防护入口。
三大陷阱(一旦离开默认值就会打开)
Rails 的默认值很出色,但下面这三项要由你有意识地守护。
① Mass Assignment
permit 得太宽,is_admin 等会被意外覆写。
② 单薄的授权
已认证但没有所有者范围。换个 ID 就能看到别人的数据(IDOR)。
③ 已知的 gem CVE
依赖 gem 的缺陷放着不修。以运行中的版本判定,快速打补丁。
此外还要留意:在 where 中用字符串拼接导致的 SQLi、把用户输入传给危险的动态方法(send/constantize),以及泄露 credentials/secret_key_base。
如何堵住这些缺口(3 步)
把 Strong Parameters 控制到最少
is_admin 这类权限字段由用户输入赋值。放弃“图省事就宽泛地 permit”。让授权显式化
current_user 限定资源范围,并用 Pundit / CanCanCan 把策略写清楚。在每一次读取/更新/删除时都检查所有权(→ IDOR 是什么)。监控 gem(依赖)的 CVE 并快速打补丁
where 中用占位符,绝不要用字符串拼接。常见(危险)
- Strong Parameters 宽泛地 permit(Mass Assignment)
- 没有授权——“已登录=能看”
- 已知的 gem CVE 放着不修
where("... #{params}")字符串拼接
正确
- permit 控制到最少
- 显式的授权(current_user/Pundit)
- gem 做 CVE 监控 + 快速打补丁
where使用占位符
本站的视角:即便有约定守护,授权和依赖仍归你自己
Rails 良好的默认值消除了大量风险,但授权——谁可以做什么,以及依赖的新鲜度,是框架无法自动守护的两件事。我们反复看到的事故,与其说是精巧的攻击,不如说是“已认证但没做所有权检查”这一类。所以重心在于:收紧 Strong Parameters、让授权显式化、并监控 gem 的 CVE。尽管这三件事并不起眼,却能阻止现实中的大多数 Rails 事故。
接下来读
- 入口:按框架的安全防护 · Laravel 安全(同为 MVC,授权形态相似)
- 实操:漏洞应对实务 · 监控依赖包的 CVE
- 术语:IDOR 是什么 · SQL 注入是什么
FAQ
QRuby on Rails 是一个安全的框架吗?
Rails 奉行『约定优于配置』,自带许多安全默认值——CSRF 防护、Strong Parameters、基于 ORM 的 SQL 防护都是标配。用得对它是一个稳固的框架,但一旦跳出默认值,或省掉必要的工作,就会开出缺口。过于宽松的 Strong Parameters、单薄的授权、未打补丁的 gem(依赖)CVE,与其说是 Rails 特有的问题,不如说更多是运营层面的问题。
Q使用 Strong Parameters 要注意什么?
Strong Parameters 会显式地允许(permit)你接受哪些字段,以防止 Mass Assignment(批量赋值到本不该赋值的字段)。危险在于为图省事而宽泛地 permit。请把允许的字段控制到最少,绝不要让 is_admin 这类权限字段可以由用户输入赋值。
Q为什么“只要登录就能看”是危险的?
那是有认证而无授权。Rails 提供了登录(认证)机制,但数据是否真的属于该用户,是你必须自己编写的、与应用相关的授权。如果你跳过按 current_user 限定资源范围、或跳过用 Pundit/CanCanCan 把策略写清楚,那么把 URL 里的 ID 换掉,就可能看到别的用户的数据(IDOR)。