乐闻世界logo
搜索文章和话题

Module Federation 的安全性如何保障?有哪些安全最佳实践?

2月19日 17:45

Module Federation 的安全性是一个重要考虑因素,以下是主要的安全问题和防护措施:

1. 跨域资源共享(CORS)安全

问题: 远程模块加载涉及跨域请求,可能被恶意利用。

解决方案:

javascript
// 配置严格的 CORS 策略 devServer: { headers: { 'Access-Control-Allow-Origin': 'https://trusted-domain.com', 'Access-Control-Allow-Methods': 'GET', 'Access-Control-Allow-Headers': 'Content-Type', 'Access-Control-Max-Age': '86400' } } // 生产环境使用白名单 const allowedOrigins = [ 'https://app1.example.com', 'https://app2.example.com' ] devServer: { setupMiddlewares: (middlewares, devServer) => { devServer.app.use((req, res, next) => { const origin = req.headers.origin if (allowedOrigins.includes(origin)) { res.setHeader('Access-Control-Allow-Origin', origin) } next() }) return middlewares } }

2. 内容安全策略(CSP)

问题: 动态加载的脚本可能违反 CSP 规则。

解决方案:

html
<!-- 配置 CSP 头 --> <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' https://trusted-cdn.com 'nonce-randomValue'; style-src 'self' 'unsafe-inline';"> <!-- 或在服务器配置 --> Content-Security-Policy: default-src 'self'; script-src 'self' https://cdn.example.com; object-src 'none'

3. 远程模块验证

问题: 加载的远程模块可能被篡改或包含恶意代码。

解决方案:

javascript
// 使用 Subresource Integrity (SRI) const loadRemoteModule = async (url, integrity) => { const response = await fetch(url) const content = await response.text() // 验证内容完整性 const computedHash = await crypto.subtle.digest( 'SHA-256', new TextEncoder().encode(content) ) const computedIntegrity = 'sha256-' + btoa(String.fromCharCode(...new Uint8Array(computedHash))) if (computedIntegrity !== integrity) { throw new Error('Module integrity check failed') } // 动态执行模块 const blob = new Blob([content], { type: 'application/javascript' }) const moduleUrl = URL.createObjectURL(blob) return import(moduleUrl) } // 使用示例 loadRemoteModule( 'https://cdn.example.com/remoteEntry.js', 'sha256-abc123...' )

4. 依赖安全扫描

问题: 共享依赖可能包含已知漏洞。

解决方案:

bash
# 使用 npm audit 扫描依赖 npm audit # 使用 Snyk 进行深度扫描 npm install -g snyk snyk test # 在 CI/CD 中集成安全扫描 # .github/workflows/security.yml name: Security Scan on: [push, pull_request] jobs: security: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Run npm audit run: npm audit --audit-level=moderate - name: Run Snyk uses: snyk/actions/node@master env: SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}

5. 权限控制

问题: 远程模块可能访问不应访问的资源。

解决方案:

javascript
// 使用沙箱隔离远程模块 class Sandbox { constructor() { this.context = Object.create(null) } execute(code) { const fn = new Function('context', ` with (context) { return (${code}) } `) return fn(this.context) } } // 限制可访问的全局对象 const sandbox = new Sandbox() sandbox.context.console = { log: (...args) => console.log('[Sandbox]', ...args) } // Proxy 拦截访问 const secureProxy = new Proxy(target, { get(target, prop) { if (allowedProps.includes(prop)) { return target[prop] } throw new Error(`Access to ${prop} is not allowed`) } })

6. HTTPS 和证书验证

问题: 中间人攻击可能导致远程模块被篡改。

解决方案:

javascript
// 强制使用 HTTPS const secureFetch = async (url) => { if (!url.startsWith('https://')) { throw new Error('Only HTTPS URLs are allowed') } const response = await fetch(url, { credentials: 'omit', mode: 'cors' }) if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`) } return response } // 配置证书固定(Certificate Pinning) // 注意:这需要在原生应用层实现

7. 版本锁定和依赖管理

问题: 依赖版本漂移可能导致安全漏洞。

解决方案:

json
// package-lock.json 确保依赖版本一致性 { "lockfileVersion": 2, "dependencies": { "react": { "version": "17.0.2", "integrity": "sha512-..." } } } // 使用 npm shrinkwrap 锁定依赖 npm shrinkwrap // 定期更新依赖并审计 npm update npm audit fix

8. 监控和日志记录

问题: 难以追踪远程模块的加载和执行情况。

解决方案:

javascript
// 模块加载监控 const moduleLoadTracker = { track(moduleName, url, status, duration) { const event = { timestamp: Date.now(), moduleName, url, status, duration } // 发送到监控系统 if (navigator.sendBeacon) { navigator.sendBeacon('/api/module-tracking', JSON.stringify(event)) } } } // 使用示例 const loadWithTracking = async (moduleName, url) => { const startTime = performance.now() try { const module = await import(url) moduleLoadTracker.track(moduleName, url, 'success', performance.now() - startTime) return module } catch (error) { moduleLoadTracker.track(moduleName, url, 'error', performance.now() - startTime) throw error } }

最佳实践总结:

  1. 使用 HTTPS:所有远程模块必须通过 HTTPS 加载
  2. 实施 CSP:配置严格的内容安全策略
  3. 验证完整性:使用 SRI 验证远程模块的完整性
  4. 定期审计:定期扫描依赖漏洞
  5. 最小权限原则:限制远程模块的访问权限
  6. 监控日志:记录所有模块加载事件
  7. 版本锁定:使用 package-lock.json 锁定依赖版本
  8. 白名单机制:只允许受信任的域名加载远程模块

通过以上安全措施,可以有效降低 Module Federation 的安全风险。

标签:Module Federation