Files
tootaio.com/docs/20251107/security-audit.md
xiaomai cc0cb01d28 fix(security): apply security hardening recommendations from audit
This commit implements several security enhancements based on the findings of a new security audit report, which has also been added to the documentation.

- **Security Headers:** Adds a strict Content-Security-Policy (CSP) and other security headers (X-Content-Type-Options, Referrer-Policy) via Nuxt route rules.
- **Production Hardening:** Disables Nuxt DevTools in production environments to reduce the attack surface.
- **Mixed Content:** All image assets are now loaded over HTTPS to resolve mixed content issues.
- **Tabnabbing:** Secures `window.open` calls by adding `noopener,noreferrer`.
- **Configuration:** Updates `.gitignore` to ignore all `.env.*` files.
- **Docs:** Adds the full security audit report for reference.
- **Build:** Corrects a case-sensitive import path to ensure cross-platform build compatibility.
2025-11-07 11:15:02 +08:00

189 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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/` 内建议信息。
# 结论与优先级
- 风险等级:低-中LowMedium。不存在明显的密钥泄露或远程代码执行面。
- 高价值、低成本修复项(建议开源前完成):
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
}
}
// 使用时:
// <UButton v-if="item.demoLink && isSafeHttpUrl(item.demoLink)" :href="item.demoLink" ... />
```
## 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` 调整、文件名大小写修复),并附上验证与回退说明。