--- title: 安全审计报告(Tootaio Studio 网站) description: 开源发布前的安全评估与加固建议与清单 lastUpdated: 2025-11-07 --- # 概览(Summary) - 架构为 Nuxt 4 + @nuxt/content 的前端站点,无自建服务端 API/上传功能,攻击面小。若开源,整体安全风险低。 - 主要关注点:外部资源使用 HTTP、窗口打开的 `opener` 风险、生产环境 DevTools 启用、缺少统一安全响应头、依赖冗余与未来内容来源治理。 ## 审计范围 - 配置与依赖:`nuxt.config.ts`、`package.json`、`.env*`、`.gitignore`。 - 前端页面与可执行逻辑:`app/` 下的页面、布局、可组合函数(composables)。 - 内容与多语言:`content/**.yml` 与 `i18n/**.json`。 - 文档与脚本:`docs/` 内建议信息。 # 结论与优先级 - 风险等级:低-中(Low–Medium)。不存在明显的密钥泄露或远程代码执行面。 - 高价值、低成本修复项(建议开源前完成): 1) 将所有外部资源统一为 HTTPS。 2) 生产环境禁用 DevTools。 3) `window.open` 显式使用 `noopener,noreferrer`。 4) 为外链/图片增加基础协议白名单校验(http/https)。 5) 通过网关或 Nitro `routeRules` 添加基础安全响应头与静态资源缓存策略。 6) 精简未使用依赖(如未使用 `better-sqlite3`)。 # 关键发现与证据(Evidence) - 公开运行时配置(非敏感): - `nuxt.config.ts:22` 暴露 `runtimeConfig.public.whatsappNumber`(按设计公开,无敏感性)。 - DevTools 在生产可能启用: - `nuxt.config.ts:14` `devtools: { enabled: true }`,建议生产禁用。 - 外链/图片使用了 HTTP(混合内容与篡改风险): - `app/pages/index.vue:83-92` 背景图 `http://img.tootaio.com/...` - `content/en-US/index.yml:25,29` 与 `content/zh-CN/index.yml:31,35` 项目图片使用 `http://`。 - 外链打开策略: - `app/pages/index.vue:37-38` 使用 `target="_blank"` 已含 `rel="noopener"`,建议补充 `noreferrer`。 - `app/composables/WhatsAppMsgSender.ts:11` 的 `window.open` 未显式 `noopener,noreferrer`。 - 统一安全头缺失: - 未在 `nuxt.config.ts` 配置 `routeRules` 的安全头(可在网关/Nginx 层或 Nitro 层补充)。 - 依赖冗余: - `package.json:19` 引入了 `better-sqlite3`,当前项目未使用,建议移除以降低供应链与构建复杂度。 - 非安全但会影响构建的细节: - `content.config.ts:2` 大小写引用与实际文件名不一致(Linux 下可能报错):应从 `./app/schemas/PricingPlanSchema` 调整为 `./app/schemas/pricingPlanSchema`。 - 环境文件治理: - `.env` 已被 `.gitignore` 忽略(`.gitignore:22`),且内容仅有公开号码(`.env:1`)。建议继续保持从未提交到历史。 # 修复与加固建议(Actionable) ## 开源前必须(High Priority) - 统一使用 HTTPS 资源 - 将 `http://img.tootaio.com/...` 统一替换为 `https://img.tootaio.com/...`。 - 建议将资源基址抽离到 `runtimeConfig.public.assetBase` 并集中管理,减少散落硬编码。 - 生产禁用 DevTools - 将 `devtools` 改为:`devtools: { enabled: process.env.NODE_ENV !== 'production' }`。 - `window.open` 加固 - 修改为:`window.open(url, '_blank', 'noopener,noreferrer')` 或在新窗口上设置 `opener = null`。 - 外链与图片的协议白名单 - 在渲染外链/图片前校验 URL 协议,只允许 `http:` 与 `https:`,避免 `javascript:`、`data:` 等危险 scheme。 - 安全响应头(建议由网关/Nginx 配置,或用 Nitro routeRules) - 最小集: - `Content-Security-Policy`(仅放行必要域名,样例见下)。 - `X-Content-Type-Options: nosniff` - `Referrer-Policy: strict-origin-when-cross-origin` - `Permissions-Policy`(按需收紧) - 静态资源缓存:`/_nuxt/**` 设置 `Cache-Control: public, max-age=31536000, immutable`。 ## 建议完成(Medium Priority) - 依赖精简 - 若未用到 `better-sqlite3`,从 `package.json` 移除并更新锁文件。 - `.gitignore` 更严格忽略 env 变体 - 将当前注释掉的 `.env.*` 忽略规则启用,并保留示例白名单: - 忽略:`.env`、`.env.*` - 白名单:`!.env.sample` - 文件名大小写一致性 - `content.config.ts` 引用改为实际文件名大小写以避免跨平台问题。 ## 可选增强(Nice-to-have) - 在 CI 中启用: - `pnpm install --frozen-lockfile` - 依赖与漏洞审计(Dependabot / `pnpm audit --prod`) - Secrets 扫描(`gitleaks`/`trufflehog`) - HSTS 与全站 HTTPS - 前置网关开启 HSTS,并确保所有外链与资源均可通过 HTTPS 访问。 # 附录:建议配置片段 ## 1) Nitro routeRules(示例) ```ts // nuxt.config.ts export default defineNuxtConfig({ // ... routeRules: { '/**': { headers: { 'Content-Security-Policy': [ "default-src 'self'", "script-src 'self'", "style-src 'self' 'unsafe-inline'", "img-src 'self' https://img.tootaio.com data:", "connect-src 'self'", "frame-ancestors 'self'", 'upgrade-insecure-requests', ].join('; '), 'X-Content-Type-Options': 'nosniff', 'Referrer-Policy': 'strict-origin-when-cross-origin', }, }, '/_nuxt/**': { headers: { 'cache-control': 'public, max-age=31536000, immutable' }, }, }, }) ``` 请按实际依赖域名精简 CSP,特别是 `img-src`、`connect-src`。 ## 2) `window.open` 安全用法(示例) ```ts const win = window.open(url, '_blank', 'noopener,noreferrer') // 或者: const win = window.open(url, '_blank') if (win) win.opener = null ``` ## 3) 外链协议白名单(示意) ```ts function isSafeHttpUrl(href: string) { try { const u = new URL(href) return u.protocol === 'http:' || u.protocol === 'https:' } catch { return false } } // 使用时: // ``` ## 4) DevTools 生产禁用 ```ts export default defineNuxtConfig({ devtools: { enabled: process.env.NODE_ENV !== 'production' }, }) ``` ## 5) `.gitignore` 建议 ```gitignore # Local env files .env .env.* !.env.sample ``` # 附注(Non-security 但建议修复) - `content.config.ts:2` 的大小写引用问题:应改为 `./app/schemas/pricingPlanSchema`(与实际文件名一致),避免在大小写敏感的文件系统上构建失败。 # 下一步 - 如需,我可以基于本报告直接提交最小化补丁(HTTPS 资源替换、`devtools` 切换、`window.open` 加固、`routeRules` 安全头、`.gitignore` 调整、文件名大小写修复),并附上验证与回退说明。