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:
@ -92,12 +92,12 @@
|
||||
<p>请填写拒绝理由:</p>
|
||||
<textarea id="rejectReason" rows="3" maxlength="500" placeholder="请输入拒绝理由..."></textarea>
|
||||
<div class="modal-actions">
|
||||
<button class="btn btn-outline" onclick="closeRejectModal()">取消</button>
|
||||
<button class="btn btn-outline" id="closeRejectModalBtn">取消</button>
|
||||
<button class="btn btn-danger" id="confirmRejectBtn">确认拒绝</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
<script nonce="{{.CSPNonce}}">
|
||||
window.__AUDIT_TYPES = {
|
||||
{{range $val, $label := .AuditTypes}}"{{$val}}": "{{$label}}",
|
||||
{{end}}
|
||||
|
||||
@ -30,4 +30,4 @@
|
||||
<div class="admin-loading" id="commentLoading" style="display:none">加载中...</div>
|
||||
|
||||
{{template "admin/layout/footer.html" .}}
|
||||
<script src="/admin/static/js/comments.js?v={{assetV "/admin/static/js/comments.js"}}"></script>
|
||||
<script src="/admin/static/js/comments.js?v={{assetV "/admin/static/js/comments.js"}}" nonce="{{.CSPNonce}}"></script>
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
</main>
|
||||
</div>
|
||||
<script src="/shared/static/js/utils.js?v={{assetV "/shared/static/js/utils.js"}}"></script>
|
||||
<script src="/admin/static/js/common.js?v={{assetV "/admin/static/js/common.js"}}"></script>
|
||||
<script src="/shared/static/js/utils.js?v={{assetV "/shared/static/js/utils.js"}}" nonce="{{.CSPNonce}}"></script>
|
||||
<script src="/admin/static/js/common.js?v={{assetV "/admin/static/js/common.js"}}" nonce="{{.CSPNonce}}"></script>
|
||||
{{if .ExtraJS}}
|
||||
<script src="{{.ExtraJS}}"></script>
|
||||
<script src="{{.ExtraJS}}" nonce="{{.CSPNonce}}"></script>
|
||||
{{end}}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@ -82,5 +82,5 @@
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
<script src="/admin/static/js/posts.js?v={{assetV "/admin/static/js/posts.js"}}"></script>
|
||||
<script src="/admin/static/js/posts.js?v={{assetV "/admin/static/js/posts.js"}}" nonce="{{.CSPNonce}}"></script>
|
||||
{{template "admin/layout/footer.html" .}}
|
||||
|
||||
@ -44,7 +44,7 @@
|
||||
|
||||
<!-- 分页 -->
|
||||
<div class="pagination-bar" id="paginationBar"></div>
|
||||
<script>
|
||||
<script nonce="{{.CSPNonce}}">
|
||||
window.__currentUid = {{.UID}};
|
||||
window.__isOwner = {{if .IsOwner}}true{{else}}false{{end}};
|
||||
// 由服务端 model.RoleDisplayNames / StatusDisplayNames 作为唯一数据源注入
|
||||
|
||||
@ -217,6 +217,8 @@ function closeRejectModal() {
|
||||
document.getElementById('rejectModal').style.display = 'none';
|
||||
}
|
||||
|
||||
document.getElementById('closeRejectModalBtn').addEventListener('click', closeRejectModal);
|
||||
|
||||
document.getElementById('confirmRejectBtn').addEventListener('click', async () => {
|
||||
const reason = document.getElementById('rejectReason').value.trim();
|
||||
if (!reason) {
|
||||
|
||||
Reference in New Issue
Block a user