安全
安全头、内容安全策略和最佳实践。
安全
Raypx 内置了安全中间件,自动为所有响应添加安全相关的 HTTP 头。本章介绍安全中间件的配置和最佳实践。
安全中间件
安全中间件位于 src/middleware/security.ts,在 src/start.ts 中注册为全局请求中间件:
export const startInstance: AnyStartInstance = createStart(() => {
return {
requestMiddleware: [securityMiddleware, i18nMiddleware, llmMiddleware],
}
})中间件按顺序执行:安全头 -> 国际化 -> LLM 内容协商。所有请求(包括 API 路由和页面路由)都会经过安全中间件。
响应头
安全中间件为每个响应设置以下 HTTP 头:
| 头部 | 值 | 说明 |
|---|---|---|
X-Content-Type-Options | nosniff | 禁止浏览器猜测 MIME 类型 |
X-Frame-Options | DENY | 完全禁止页面被嵌入 iframe |
Referrer-Policy | strict-origin-when-cross-origin | 仅发送来源域名给同源请求 |
Permissions-Policy | camera=(), microphone=(), geolocation=() | 禁用摄像头、麦克风和地理位置 API |
X-XSS-Protection | 0 | 禁用旧版 IE XSS 过滤器(现代浏览器使用 CSP 替代) |
生产环境 HSTS
当 NODE_ENV=production 时,中间件会自动添加 HSTS 头:
Strict-Transport-Security: max-age=63072000; includeSubDomains; preload| 指令 | 值 | 说明 |
|---|---|---|
max-age | 63072000(2 年) | 浏览器在此期间强制使用 HTTPS |
includeSubDomains | - | HSTS 策略适用于所有子域名 |
preload | - | 允许被加入浏览器的 HSTS 预加载列表 |
HSTS 仅在生产环境启用。一旦启用且客户端收到该头,在 max-age 期间内无法降级为 HTTP。请确保你的站点已正确配置 HTTPS 后再部署到生产环境。
CSP 配置
内容安全策略(Content-Security-Policy)根据环境动态生成:
开发环境
default-src 'self';
script-src 'self' {origin} 'unsafe-inline' 'unsafe-eval';
style-src 'self' 'unsafe-inline';
img-src 'self' data: blob: https://*.googleusercontent.com;
font-src 'self' data:;
connect-src 'self' {origin};
frame-ancestors 'none';
base-uri 'self';
form-action 'self'开发环境允许 'unsafe-inline' 和 'unsafe-eval',以兼容 HMR(热模块替换)和开发工具。
生产环境
default-src 'self';
script-src 'self' {origin};
style-src 'self' 'unsafe-inline';
img-src 'self' data: blob: https://*.googleusercontent.com;
font-src 'self' data:;
connect-src 'self' {origin};
frame-ancestors 'none';
base-uri 'self';
form-action 'self'生产环境移除了 'unsafe-eval',限制脚本来源仅允许自身和站点域名。style-src 仍保留 'unsafe-inline' 以兼容 Tailwind CSS 的运行时样式注入。
CSP 指令说明
| 指令 | 说明 |
|---|---|
default-src 'self' | 默认只允许同源资源 |
script-src | 控制脚本来源 |
style-src 'unsafe-inline' | 允许内联样式(Tailwind CSS 需要) |
img-src | 允许图片来源,包括 data URL、blob 和 Google 头像 |
font-src | 允许字体来源 |
connect-src | 控制 fetch/XHR 连接目标 |
frame-ancestors 'none' | 禁止被任何页面嵌入(等同于 X-Frame-Options: DENY) |
base-uri 'self' | 限制 <base> 标签的 URL |
form-action 'self' | 表单只能提交到同源 URL |
生产环境建议
以下建议适用于将 Raypx 部署到公网生产环境的场景。
必须配置
- HTTPS -- 生产环境必须使用 HTTPS。HSTS 头会在浏览器端强制 HTTPS,但首次访问仍需 HTTPS 支持
AUTH_SECRET-- 使用至少 32 字符的强随机字符串,切勿使用默认值或弱密码APP_KEY-- 设置应用加密密钥,用于敏感数据加密- 环境变量安全 -- 通过
.env文件管理密钥,确保.env已添加到.gitignore
推荐配置
- Rate Limiting -- Raypx 内置了基于内存的速率限制器(
src/lib/rate-limit.ts),建议在生产环境中对 API 端点启用 ADMIN_EMAILS-- 指定管理员邮箱列表,限制管理功能的访问权限- CORS -- 如果需要跨域 API 访问,在反向代理层面配置 CORS 策略
- 日志监控 -- 配置应用日志收集和错误监控服务
CSP 自定义
如果你的应用需要加载额外的外部资源(如第三方脚本、字体、分析工具),需要修改 src/middleware/security.ts 中的 CSP 配置。例如添加 Google Analytics:
const scriptSrc = isProduction
? `'self' ${origin} https://www.googletagmanager.com`
: `'self' ${origin} 'unsafe-inline' 'unsafe-eval'`