fix(security): 修复客户端认证与地图渲染漏洞 (#5)

## 安全修复

- 修复地图标记与悬浮卡片中的存储型 XSS
- 限制登录后的重定向目标为当前站点
- 提前清除邮箱确认和密码重置 URL 中的令牌
- 将 Vite 升级到 8.0.16,修复已公开的高危漏洞
- 收紧 Referrer Policy 并增加 HSTS

## 验证

- `npm audit --audit-level=low`:0 个漏洞
- `npm run build`
- 6 组正常与恶意重定向用例
- 危险 DOM API 残留检查Reviewed-on: #5
This commit was merged in pull request #5.
This commit is contained in:
2026-07-23 02:41:43 +08:00
parent 16b3dd4aaa
commit 02399ffae8
7 changed files with 161 additions and 111 deletions
+7 -4
View File
@@ -10,6 +10,11 @@ const router = useRouter()
const state = ref<'loading' | 'success' | 'failed'>('loading')
const countdown = ref(5)
let countdownTimer: ReturnType<typeof setInterval> | null = null
const confirmationToken = typeof route.query.token === 'string' ? route.query.token : ''
if (route.query.token !== undefined) {
window.history.replaceState(window.history.state, '', window.location.pathname)
}
function startCountdown() {
countdownTimer = setInterval(() => {
@@ -23,8 +28,7 @@ function startCountdown() {
onMounted(async () => {
try {
const token = typeof route.query.token === 'string' ? route.query.token : ''
if (!token) {
if (!confirmationToken) {
state.value = 'failed'
return
}
@@ -32,9 +36,8 @@ onMounted(async () => {
await apiRequest('/auth/confirm-email', {
method: 'POST',
auth: false,
body: { token },
body: { token: confirmationToken },
})
window.history.replaceState(null, '', window.location.pathname)
state.value = 'success'
startCountdown()
} catch {