fix: CSP 策略移除 unsafe-inline,改用 nonce 机制

- SecurityHeaders 中间件生成随机 nonce,注入 context
- BuildPageData/BuildAdminPageData 将 CSPNonce 传递给模板
- 所有 19 个模板文件 <script> 标签添加 nonce 属性
- 移除所有内联事件处理(onclick/onerror),改用事件监听
- 移除所有 javascript:void(0) 链接,改用 # 号 + preventDefault
- utils.js 添加全局 avatar 图片加载失败回退处理
- common.js 登出按钮添加 preventDefault
- audit.js 关闭弹窗按钮改用事件监听
This commit is contained in:
2026-06-02 16:10:23 +08:00
parent 9477155bcf
commit 53f18ca6ee
25 changed files with 122 additions and 55 deletions

View File

@ -20,7 +20,7 @@
<li class="nav-avatar-wrapper">
<a href="/space" class="nav-avatar-link">
{{if .Avatar}}
<img src="{{.Avatar}}" alt="" class="nav-avatar" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'">
<img src="{{.Avatar}}" alt="" class="nav-avatar">
<span class="nav-avatar nav-avatar-default" style="display:none">{{substr .Username 0 1}}</span>
{{else}}
<span class="nav-avatar nav-avatar-default">{{substr .Username 0 1}}</span>
@ -30,7 +30,7 @@
<div class="nav-dropdown-header">
<div class="nav-dropdown-avatar">
{{if .Avatar}}
<img src="{{.Avatar}}" alt="" onerror="this.style.display='none';this.nextElementSibling.style.display='flex'">
<img src="{{.Avatar}}" alt="">
<span style="display:none">{{substr .Username 0 1}}</span>
{{else}}
<span>{{substr .Username 0 1}}</span>
@ -47,7 +47,7 @@
<svg class="nav-dropdown-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/></svg>
<span>个人中心</span>
</a>
<a href="javascript:void(0)" class="nav-dropdown-item nav-logout" id="logoutBtn">
<a href="#" class="nav-dropdown-item nav-logout" id="logoutBtn">
<svg class="nav-dropdown-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M9 21H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h4"/><polyline points="16 17 21 12 16 7"/><line x1="21" y1="12" x2="9" y2="12"/></svg>
<span>退出登录</span>
</a>