Public Security Baseline - wongyiuming/FrontierCloud-Gin GitHub Wiki

公开网站安全基线:成因、实际影响与修复

依据维护者提供的 2026-10-08 DNSPup 配置扫描,对源码和公开响应作了交叉检查。这不是完整渗透测试;评分不能证明业务没有漏洞,也不能把所有扣分项都称为可利用漏洞。

问题是怎样产生的

项目 原代码/配置的成因 实际影响与本轮处理
主页面缺 CSP 通用 nginx/security-headers.conf 原来只包含五类响应头,CSP 只在部分卡拉 OK 配置出现;Gin 的普通 HTML 渲染也不生成策略。 如果另一处存在 HTML/脚本注入,浏览器缺少一层阻止其执行的防线。没有据此证明已存在 XSS 或发生入侵。现统一生成每次响应独立的 256 位 nonce,可信模板在插入用户数据前标记脚本,禁用内联事件和 eval。
播放列表内联事件 player.js 原来通过 innerHTML 拼接 onclick="selectMedia(index)",把事件代码和 DOM 内容混在一起。 原实现本身不能证明注入,但会与严格 CSP 冲突;为使它工作而开放 unsafe-inline 会失去重要保护。现改用列表容器事件代理,刷新列表后仍可选曲;浏览器实测验证正常播放及恶意事件被阻止。
维护页面丢安全头 Nginx 子 location 自己有 add_header Cache-Control 时,不会自动继承父层那组 add_header;维护页就是这个结构。 维护窗口的 503 页面防护弱于正常页面,单查正常 200 无法发现。现该 location 显式包含完整头,并且只允许固定维护脚本/CSS 的精确 SHA256;上游 503 内部跳转同样使用维护页策略。
子路径重复安全头与内部元数据过滤遗漏 卡拉 OK 单独声明 proxy_hide_header Cache-Control,以及中继单独声明 Cookie/内部跳转过滤时,替换了父层整组过滤名单。修复最初只覆盖普通首页,预发布终验发现卡拉 OK 返回两份策略。 当前重复的策略相同,尚未发现因此导致卡拉 OK 故障;但未来策略不同会被浏览器共同执行,可能误拦合法脚本/权限。中继还可能暴露内部资源/审计标识。现各子层显式引入共享名单,真实测试覆盖每条公开页面及故意返回冲突头的模拟存储。
录音中继未忽略上游内部跳转 媒体中继已有 proxy_ignore_headers X-Accel-Redirect,录音中继缺少;隐藏响应头不等于禁止 Nginx 处理该头。 异常或被控制的存储响应可能指示主节点改走内部路由。影响取决于可达内部路由及其鉴权,未证实生产环境已被利用。现对录音中继也忽略该指令,真实 Nginx 测试断言模拟上游不能改变响应目的地。
Nginx 版本暴露 未关闭默认 server_tokens,响应告诉外界精确版本。 方便攻击者筛选已知版本缺陷,但版本号本身不导致远程执行。关闭版本展示,仍正常显示 Nginx 产品名;持续更新不能被“隐藏版本”替代。
TLS 配置未统一 业务 TLS server 配置 TLS 1.2/1.3,默认 TLS server 未显式共享该策略;旧 cipher 选择为宽泛的 HIGH:!aNULL:!MD5。 容易在新增虚拟主机或升级默认值时出现策略漂移。扫描中的业务站点已有 TLS 1.2/1.3,不能宣称已发现旧 TLS 可利用。现两个 server 共用明确的 TLS 1.2/1.3、ECDHE/AEAD 策略及会话设置。
没有 HTTP/2 TLS 监听没有启用 HTTP/2,ALPN 仅协商 HTTP/1.1。 属于性能/兼容性问题,不是入侵漏洞;高延迟下并行页面资源可能受连接数量影响。现支持 HTTP/2 并保留 HTTP/1.1。没有用本轮结果宣称车机首屏问题已解决。
后台重定向丢高位端口 Nginx /admin/ 代理 location 对不带尾斜杠的入口自动生成绝对重定向,使用容器的 443 而非宿主随机高位端口。 真实浏览器测试确认新地址不含原端口,导致测试入口连接失败;正式站点的 443 不受影响。这是既有可用性缺陷,不是入侵证据。现显式返回相对 308,浏览器从原登录入口跟随重定向,断言端口不变。
标准文件生成地址丢配置端口 初版公开 origin 拼接只选择协议和域名,没有保留部署端口。GitHub 自动审查发现非默认端口部署会生成错误 sitemap/security.txt 地址。 新环境访问发现文件时链接不可用,不是密钥泄露。现验证显式 PUBLIC_ORIGIN 或配置的公开 TLS/HTTP 端口,拒绝用户输入 Host 替代;动态未知端口仅让发现文件返回 503,不影响业务。补配置、真实 Compose 及浏览器回归。
邮件域名未声明策略 域名没有邮件业务,却也没有明确的 Null MX、SPF、DMARC。 外部发件人伪造本域名时,收件方缺少域名所有者的明确拒绝策略;并不表示网站会自行发垃圾邮件。DNS 层建议见下表,需维护者手动配置。
缺 DNSSEC / CAA DNS/注册商侧没有启用签名链和 CA 发行限制,不是 Gin 路由遗漏。 DNSSEC 可让验证解析器拒绝被篡改的 DNS 答复;CAA 限制可发行证书的 CA,但不能替代域名所有权验证。两者均未在本轮擅自修改。
缺标准文件 应用没有对应路由,也未提供真实漏洞接收联系方式。 robots/sitemap 是爬虫与索引提示,不是访问控制;security.txt 缺失会让研究人员难以联系维护者,不能证明可被入侵。现 sitemap 仅列三类公开落地页,不公开媒体清单;security.txt 仅在配置真实联系方式后启用。

新增 nonce HTML 禁止存储;卡拉 OK 的边缘缓存也统一为 private, no-store。旧文档接口测试把完整缓存字符串固定成 no-store,加入更严格的指令后误报;现检查独立的 no-store 指令,仍会拒绝可缓存响应。这是测试断言问题,不是已发生的数据泄露。

为什么既有测试没有提前拦住

原维护门禁测试验证的是关闭、强制打开和后台例外行为,最小 Nginx fixture 没有装载完整生产安全头文件;因此功能门禁能通过,响应头继承问题仍可能漏检。播放器的 Node/VM 功能烟测不执行真实浏览器 CSP,也不能证明内联事件在严格策略下可用。此次增加生产头文件挂载、固定错误页 hash 契约、真实 HTTPS/Chromium 正向业务与负向脚本测试,并保留 SQLite/MySQL API 和 Go race 回归。轻量契约进三分钟 CI,真实构建及浏览器留在开发机;不是把重测试转移到 GitHub。

首次候选的浏览器测试只断言首页 CSP 数量,卡拉 OK 只验证功能,所以重复但相同的头未使它失败;预发布全路径数量检查及时拦住了发布。已补六类安全头在音乐、视频、卡拉 OK 路径的唯一性,以及模拟不可信存储的真正 Nginx 过滤/内部跳转测试。未把未通过终验的候选提交到 main。

这些问题来自覆盖面不完整、默认配置和 DOM/事件代码混写,不是 Go/Gin 语言天然造成的。没有入侵证据时不能把配置风险报告成已经发生的密钥或媒体泄露。

没有为了评分盲目修改的项目

  • 保留 HTTPS 一年 HSTS;没有核实全部子域名 HTTPS 前,不启用 includeSubDomains / preload,以免锁死合法业务。
  • Let's Encrypt 已在 2025-08-06 终止 OCSP,使用 CRL;缺少 stapling 不应通过配置失效的 OCSP 服务来“修复”。
  • 没有 CDN/WAF/Anycast 不自动构成漏洞;启用前必须验证直连存储高位端口、Range、上传和流式播放。
  • 麦克风只允许同源卡拉 OK 页面使用;播放器、摄像头、定位不额外授权。
  • 动态 CSS、HTTPS 存储连接和 blob 媒体是兼容性例外;没有给脚本开放 unsafe-inline / unsafe-eval。既有鉴权文档 CDN 脚本仍是供应链依赖,不声称 CSP 消除了全部风险。

维护者的 DNS / 配置待办

维护者确认 520mall.cc 没有邮箱业务。不要部署邮件服务器或虚构报告邮箱。

类型 名称 值
MX @ 优先级 0,目标 .(Null MX)
TXT @ v=spf1 -all
TXT _dmarc v=DMARC1; p=reject; sp=reject; adkim=s; aspf=s

不要建立重复 SPF/DMARC;未来包括子域名在内需要发信时,先调整策略。CAA 仅在确认全部证书均由 Let's Encrypt 签发后设置 0 issue "letsencrypt.org";DNSSEC 先从 Cloudflare 获取真实 DS,再到 NameSilo 发布并验证签名链。DNS 变更不在源码发布中自动执行。

提供一个真实有人监控的 HTTPS 漏洞报告页面或外部邮箱,设为 SECURITY_CONTACT;未配置时 security.txt 故意返回 404,不用占位邮箱欺骗扫描器。现有原生升级保留容器环境,新环境变量需要按当前固定镜像显式重建 Web 服务,不能仅靠升级按钮添加。

验证与发布证据

2026-10-09 16:15:36(北京时间),开发机针对最终精确 dev 提交 e033c3ad8f57392cc5e2f41900e7d2abd891d151 完成全部门禁,日志最后明确记录 ALL DEVELOPMENT GATES PASSED。首次候选 09d9d7c 预发布发现卡拉 OK 重复头,未晋升 main;后续 e1abcdc 完成一轮全验收,再修正自动审查的非默认公开端口问题及新装 fixture 配置传递,并完整重跑,未沿用旧提交的测试结论。

  • 轻量 Python 发现 108 项、环境约定跳过 2 项,另有策略/资产检查和 Node 功能烟测;不能把跳过算成通过。
  • 全部 Go 包、真实 MySQL/Redis 业务、进程停写与全包 race、实际 Nginx 维护门禁通过。
  • 新增真实 Nginx 模拟上游边界门禁通过;完整公开音乐、视频、卡拉 OK 的六类安全头逐项唯一性检查通过。
  • Python 黑盒驱动测试对象为真实 Gin;SQLite / MySQL 各八个场景通过,八是该黑盒组件的场景数,不是项目测试总数。
  • 真实 HTTPS/Chromium 验证 HTTP/2、TLS 1.2/1.3、旧 TLS 拒绝、Range、选曲播放、Admin、卡拉 OK、麦克风范围、三类恶意脚本拦截和哈希维护页 503;从原后台入口跟随相对 308,端口与查询参数均保留。
  • 最终精确 dev CI #17 成功;真实构建/数据库/浏览器没有加入三分钟测试 CI。
  • 最终事件 CD 通知 成功。精确 e033c3a 原生日志 success/complete、维护解除;20:31 左右(北京时间)再次确认 web/nginx/updater 一致,公网逐页安全头唯一性、nonce、HTTP/2、后台相对跳转、404、标准文件及健康验收全部通过,同机生产存储仍为 8a6e309。自动 GitHub 审查于 16:25 完成,未对最终提交提出新增问题;没有人工 Codex 审查或新增付费。
  • dev → main PR #4 已合并为 6adfec485488bdcd8393e856f86896c25929aa1b;main 晋升 CI #18 成功约 7 秒,dev 快进后 CI #19 成功约 12 秒。20:33:44(北京时间)预发布已完成合并提交的原生交接,维护关闭;生产主节点和存储实例没有随之升级。

生产升级由维护者执行。本轮没有生产/DNS变更,也没有车机同运营商弱网验收;不能将浏览器 fixture 或预发布正常结果称为全网无漏洞证明。

源码说明:public-security-baseline.md。参考:CSP、Nginx add_header 继承、security.txt、Null MX、Let's Encrypt OCSP 退役。