Skip to content

Security: Lling0000/Token_Famer

Security

docs/security.md

Security Guide

安全边界

浏览器、模型 API 客户端、邮件链接、支付通知、上游响应和管理员输入全部不可信。Caddy 是公网边界,Fastify 是认证与业务授权边界,PostgreSQL 约束是余额和唯一性的最终边界。

沙箱标记不能代替安全控制。Mock 上游和支付宝沙箱仍使用与生产相同的鉴权、幂等、日志脱敏和事务路径。

身份与会话

  • 注册需要有效邀请码、规范化邮箱和经过验证的邮箱所有权。
  • 密码由认证库使用当前安全默认算法哈希;应用不自行实现密码学。
  • 会话 Cookie 设置 HttpOnlySecureSameSite=Lax,采用窄 Domain/Path,并在登录、提权和密码变更后轮换。
  • 状态写请求同时验证 SameSite/CSRF Token 和受控 Origin;CORS 只允许正式 Web Origin。
  • TOTP Secret 使用服务端密钥加密保存。恢复码只显示一次,逐个哈希保存,使用后立即失效。
  • 创建/重置 API Key、关闭 2FA、更换邮箱、发起退款和管理员余额调整要求近期重新认证。
  • 用户冻结立即撤销 Web 会话和 API Key 使用权,但不删除审计或账本。
  • 登录、邀请码、找回密码、邮箱验证和 TOTP 校验按 IP 与账号双维度限流;错误消息不泄露账号是否存在。

API Key

  • Key 格式为 sk-tf-<public-prefix><secret>,secret 至少 256 bit CSPRNG 熵。
  • 完整 Key 只在创建响应展示一次;数据库只保存可索引前缀和使用服务端 Pepper 的 HMAC-SHA-256 摘要。
  • Pepper 只存在服务器 Secret,轮换时支持当前和上一个 Pepper 的短期双验证,不写日志。
  • 每个用户最多 5 个活动 Key。Key 可以命名、设置模型/速率限制并立即撤销。
  • 比较摘要使用恒定时间函数。不存在、撤销和错误 Key 对外返回同类认证错误。
  • Authorization、x-api-key、Cookie、TOTP、恢复码和完整 Key 必须被日志、错误跟踪、Tracing 与代理访问日志脱敏。

Provider 与 Secret

  • TeamoRouter、模型上游、Alipay、邮件和对象存储通过 Adapter,凭据不进入 Domain 或 Contracts。
  • .env.example 只有名称和占位符;生产 Secret 存在权限 600 的服务器 .env.production 或后续 Secret Manager。
  • 容器按最小权限运行,只给需要的服务挂载对应 Secret。Web 镜像不包含数据库、支付、上游或 Pepper。
  • 不在浏览器 NEXT_PUBLIC_* 中放任何 Secret。
  • CI 使用专用测试凭据和 Mock Provider;Fork PR 不获得生产 Environment Secret。
  • 日志禁止记录用户 Prompt、模型响应正文、支付私钥、签名原文、认证 Header 或数据库 URL。

模型网关

  • 默认只启用 Mock 上游;真实 Adapter 需要显式环境开关、授权记录和发布批准,不能因存在 Key 自动启用。
  • 请求体设大小上限、模型白名单、超时、并发和速率限制。未知字段按兼容 Spec 处理,但不能传入内部管理参数。
  • 调用前原子预留保守上限;可用余额不足时不请求上游。
  • 流式客户端断开后,服务端在有界时间内继续读取最终 usage 并结算;缺失 usage 使用保守预留并进入对账,不能免费放行。
  • 上游错误经过 Adapter 映射,不把上游认证信息、内部 URL 或完整响应头返回给客户端。
  • 模型请求审计保存模型、Token usage、价格版本、状态、时长和请求 ID,不保存内容正文。

支付

  • 浏览器只提交 SKU 和幂等键;金额、币种和 Token 数由服务端已发布商品版本决定。
  • 回调先按 Provider 官方规则验签,再核对 App ID、商户订单、Provider 交易号、金额、币种和订单状态。
  • Provider 事件 ID 与交易号建立唯一约束。相同回调重复 10 次仍只能产生一次 Wallet 入账。
  • 不能仅凭浏览器跳转成功页或客户端轮询参数认定付款成功。
  • 状态机为 pending -> paid -> credited -> refunded,另有 expired 终态;非法倒退或跳转被拒绝并审计。
  • 回调原文只在确有审计需要时加密短期保存;日志只保留事件 ID、订单 ID 和脱敏结果。
  • 退款通过 Payment Service 和 Wallet 冲正流水处理,不直接减少余额。余额不足、部分退款等策略在启用真实支付前专项设计。

游戏与经济滥用

  • 服务端忽略客户端提交的价格、产量、成熟状态、随机值、亲密度、偷取数量和余额。
  • 所有奖励、支付、收获、偷取和激活具有幂等键与数据库唯一业务引用。
  • 同一地块收获和偷取锁定同一 Planting;可用余额与准备金有数据库非负约束。
  • 随机 seed 使用 CSPRNG,公开 commit 后不可替换;规则版本和结果可审计。
  • 管理员没有直接 SQL 改余额功能。人工调整要求 2FA、近期认证、原因、工单/事件号和补偿账本。
  • 对注册、好友请求、帮助、偷取、领取奖励、下单和 API 调用分别限流,检测多账号和回调重放异常。

Web 与基础设施

  • Caddy 强制 HTTPS,HTTP 只重定向;证书自动续期并监控到期时间。
  • 正式域名启用 HSTS、CSP、X-Content-Type-Options: nosniff、合适的 Referrer-Policy 和 frame 限制。
  • CSP 使用 nonce/hash,不为方便启用全局 unsafe-inline;第三方资源域名逐项批准。
  • 数据库、Redis、内部 API、Mock/New API 不绑定公网地址。公网安全组与主机防火墙只允许 22/80/443
  • SSH 禁用密码登录和 Root 密码认证;完成首次部署后使用独立 sudo 部署用户、限制来源 IP,并保留经过验证的应急访问。
  • 容器设置只读根文件系统(可行处)、非 Root 用户、资源上限、健康检查、日志轮转和固定镜像版本/digest。

数据、日志与备份

  • 收集完成业务和安全所必需的最少数据。排行榜公开持有量必须由用户主动加入。
  • 日志使用结构化事件和请求 ID。生产默认不记录请求/响应正文。
  • 审计日志追加写,记录操作者、动作、目标、结果、UTC 时间和业务原因;不包含 Secret。
  • PostgreSQL 备份在离开服务器前加密,访问权限与生产数据库分离;按运行手册定期执行恢复演练。
  • 删除账号不能破坏法律、支付、账本和反滥用所需记录;对外展示数据应匿名化,保留策略在公开运营前完成法律审查。

安全验证

以下变更必须运行完整 pnpm verify 并增加专项测试:

  • Auth:枚举、限流、会话轮换、CSRF、2FA 恢复码和冻结撤销。
  • API Key:一次展示、摘要验证、撤销、日志脱敏、错误一致性。
  • Wallet:并发预留、余额不为负、流水守恒、冲正和幂等。
  • Payment:签名、金额核对、非法状态、十次重放、查单分歧和退款。
  • Gateway:余额不足、流式断开、usage 缺失、超时、上游错误和内容不落日志。
  • Deployment:端口扫描、HTTPS、安全头、Secret 文件权限、备份恢复和上一版本回滚。

发现真实 Secret 进入 Git 时,先撤销/轮换 Secret,再清理历史并审计使用情况;只删除文件不算完成处置。

There aren't any published security advisories