5月30日 23:35

Module Federation 如何保障远程模块安全?

Module Federation 的安全边界不在“能不能加载远程模块”,而在“只加载谁、加载什么版本、出问题时能不能立刻止损”。remoteEntry.js 本质上是运行时脚本,一旦来源被污染,Host 会把风险带进自己的页面。所以安全方案要同时管住域名、传输、依赖、权限和监控,不能只靠一条 CORS 配置。

远程入口应该先被白名单约束

生产环境不要把 Access-Control-Allow-Origin 写成 *,尤其是带登录态的管理台或 B 端系统。Host 和 Remote 最好维护一份明确的域名清单,构建时注入,运行时再校验一次。这样做的代价是新增 Remote 需要发布配置,但边界清楚,排查也快。

js
const remotes = { account: 'https://cdn.example.com/account/remoteEntry.js' } function assertTrusted(url) { const allow = ['https://cdn.example.com', 'https://assets.example.com'] if (!allow.includes(new URL(url).origin)) throw new Error('untrusted remote') }

CORS 只解决浏览器是否允许取资源,不等于证明资源可信。踩坑最多的是测试环境为了省事全开放,后来配置被复制到生产。更稳妥的做法是 CDN、网关和应用配置三处都只放行可信来源。

CSP 和 HTTPS 是最低防线

CSP 要把 script-src 收紧到 Host 自身和可信 CDN,避免任何页面都能临时塞一个远程脚本。Module Federation 会动态加载 chunk,所以还要把 Remote 的 chunk 域名一起列进去。这里的取舍是配置会变复杂,但它能把 XSS 和供应链污染的影响范围压小。

http
Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'; base-uri 'self'

所有 remoteEntry 和 chunk 都必须走 HTTPS。证书、HSTS、CDN 回源鉴权这些听起来不像前端问题,但它们决定用户拿到的脚本是不是你发布的那一份。不要在客户端拼接未校验的 URL,也不要允许业务参数直接决定 Remote 地址。

完整性、版本和依赖要一起管

如果发布链路能生成 manifest,可以把 remoteEntry 的 hash、版本号和构建时间写进去,Host 加载前先比对。SRI 对动态脚本有使用边界,很多团队会改用 manifest 校验加 CDN 不可变路径。关键不是迷信某个机制,而是让“被篡改的文件”无法悄悄上线。

共享依赖也要审计。reactvue@angular/core 这类单例依赖要锁定版本范围,安全补丁通过统一升级推进。singleton: true 能减少重复实例,但如果版本差太大,运行时错误会更隐蔽;安全敏感系统建议配合 requiredVersion 和灰度发布。

权限不要默认交给 Remote

Remote 组件不应该直接拿全局 token、路由实例或完整用户对象。Host 可以只传必要的 props,或者提供受限的 SDK,比如 request('/profile') 而不是暴露原始 fetch。这样会牺牲一点开发自由度,但能避免一个子应用越权访问所有资源。

追问

CORS 配成白名单是不是就安全了?

不是,CORS 只是在浏览器层控制跨域读取,不能证明脚本没有被 CDN、发布流程或依赖污染。它适合做第一道门禁,但不能替代 CSP、HTTPS、完整性校验和发布审计。边界在于:攻击者如果已经控制了可信域名上的文件,CORS 白名单也拦不住。实际项目里常见坑是把开发环境的 * 带到生产,后面再补监控已经晚了。

CSP 会不会影响 Module Federation 的动态加载?

会,尤其是 Remote 还会再加载自己的异步 chunk 时,script-src 少配一个 CDN 域名就会白屏。取舍是 CSP 越严格越安全,但发布和域名治理成本也越高。建议把 Remote 统一收敛到少数 CDN 域名,而不是每个团队随便开新域。排查时先看浏览器控制台的 CSP violation,比盲改 webpack 配置快。

远程模块需要放进沙箱吗?

不是所有 Remote 都需要 iframe 或 ShadowRealm 级别的隔离。普通业务组件通常用权限收口、只读上下文和错误边界就够了;第三方插件、低信任团队代码或可配置脚本才更适合强沙箱。沙箱的代价是通信、样式、性能和调试都会变麻烦。边界判断很简单:如果 Remote 出问题可能泄露 token 或改写关键交易流程,就不要只当普通组件加载。

如何在发布流程里发现被污染的 remoteEntry?

CI 里至少要做依赖扫描、产物 hash 记录和 manifest 校验,线上再监控加载来源、版本和失败率。安全扫描不能只跑 Host,Remote 仓库也要同样执行,否则共享依赖漏洞会绕进来。踩坑点是只监控 200 状态码,却没记录实际加载的版本和 hash。真正有用的日志应该能回答:用户加载了哪个 Remote、来自哪个 URL、耗时多少、是否命中预期版本。

结论

Module Federation 的安全实践不是单点配置,而是一套供应链控制。可信域名、HTTPS、CSP、版本锁定、最小权限和加载监控都要同时存在。只要把 Remote 当成“会在 Host 页面里运行的外部代码”,很多安全决策就会自然变得保守。

标签:Module Federation