fix(security): 修复安全审计的 P1/P2/P3 项,含全局复查新发现的两处越权与外跳
P1: - 外链图片:markdown 渲染层只放行站内与自有 CDN 图片。配置里的 image_bucket_cdn_host 常写成 host/path,统一归一化后再比对,避免把自家图一起剥掉 - 密码:页面/提问密码最小 6 位;密码比对挪到验证码之后;页面密码失败锁定 5 次/10 分钟 - 客户端 IP:CF-Connecting-IP / EO-Client-IP 只在 TCP 对端可信(回环或 trusted_proxies) 时采信,公网对端带来的权威头一律忽略 P2/P3: - 跳转参数收敛到 shared.SafeRedirectTarget:拒反斜杠与控制字符(url.Parse 会把 %0d%0a 解成 CRLF,伪造 Location),最后再用 path.Clean 验一次前缀 - 注册不再暴露「邮箱已注册 / 已停用」:与全新注册共用同一个成功出口,只在日志留痕 - CSP:默认 enforce,白名单由配置派生,覆盖 umami(运行时注入)、Turnstile 与 按 sentry_dsn 条件放行的 Sentry CDN - /user 与 /_ 下发 no-store;补 X-XSS-Protection、Permissions-Policy,并把安全头前移到 静态资源中间件之前(原先静态文件拿不到 nosniff/HSTS) - 封禁事实落库 ban_records;429 统一带 Retry-After 与本地化文案 - token 比较改常量时间;探索页页码上限;JSON 响应显式 Content-Type 全局复查补的两处: - 私聊 SendMessage 的 POST 缺 conv.OwnerID 校验,被拉黑者可换 domain 继续发消息 - 页面密码 next 与登录 to 同源的反斜杠外跳 验收:verify_p1_fixes 4/4、verify_round2 19/19、verify_page_next 6/6、 verify_chat_owner 3/3(含变异对照);单测与 go build ./... 全通过。
This commit is contained in:
+21
-17
@@ -16,21 +16,22 @@ var jaDict = map[string]string{
|
||||
"nav.lang": "言語",
|
||||
|
||||
// 共通
|
||||
"common.login": "ログイン",
|
||||
"common.forgot": "パスワードを忘れた",
|
||||
"common.submit": "送信",
|
||||
"common.cancel": "キャンセル",
|
||||
"common.save": "保存",
|
||||
"common.close": "閉じる",
|
||||
"common.delete": "削除",
|
||||
"common.moveUp": "上へ移動",
|
||||
"common.moveDown": "下へ移動",
|
||||
"common.share": "共有",
|
||||
"common.verifying": "認証中...",
|
||||
"common.submitting": "送信中...",
|
||||
"common.uploading": "アップロード中...",
|
||||
"common.lang": "言語",
|
||||
"common.menu": "メニュー",
|
||||
"common.login": "ログイン",
|
||||
"common.forgot": "パスワードを忘れた",
|
||||
"common.submit": "送信",
|
||||
"common.cancel": "キャンセル",
|
||||
"common.save": "保存",
|
||||
"common.tooManyRequests": "リクエストが多すぎます。しばらくしてから再度お試しください。",
|
||||
"common.close": "閉じる",
|
||||
"common.delete": "削除",
|
||||
"common.moveUp": "上へ移動",
|
||||
"common.moveDown": "下へ移動",
|
||||
"common.share": "共有",
|
||||
"common.verifying": "認証中...",
|
||||
"common.submitting": "送信中...",
|
||||
"common.uploading": "アップロード中...",
|
||||
"common.lang": "言語",
|
||||
"common.menu": "メニュー",
|
||||
|
||||
"common.pleaseWait": "お待ちください...",
|
||||
"common.backHome": "ホームに戻る",
|
||||
@@ -182,9 +183,9 @@ var jaDict = map[string]string{
|
||||
"admin.tagInputHint": "入力して Enter またはカンマで追加",
|
||||
"admin.tagInputDuplicate": "既に存在するため無視しました",
|
||||
"admin.pagePassword": "ページアクセスパスワード",
|
||||
"admin.pagePasswordHint": "アクセスパスワードを設定(空欄で無効)",
|
||||
"admin.pagePasswordHint": "アクセスパスワードを設定(6〜30文字、空欄で無効)",
|
||||
"admin.askPassword": "質問パスワード",
|
||||
"admin.askPasswordHint": "質問用パスワードを設定(空欄で無効)",
|
||||
"admin.askPasswordHint": "質問用パスワードを設定(6〜30文字、空欄で無効)",
|
||||
"admin.saveProfile": "変更を保存",
|
||||
"admin.updated": "プロフィールを更新しました",
|
||||
"admin.logout": "ログアウト",
|
||||
@@ -618,6 +619,7 @@ var jaDict = map[string]string{
|
||||
"vote.page.submit": "投票する",
|
||||
"vote.page.alreadyVoted": "この投票にはすでに参加済みです。ありがとうございます!",
|
||||
"vote.page.resultsTitle": "投票結果",
|
||||
"vote.page.anonymousNotice": "匿名投票(お一人一票)のため、結果は参考値です。",
|
||||
"vote.page.totalVotes": "総参加",
|
||||
"vote.page.avgRating": "平均点",
|
||||
"vote.page.avgRank": "平均順位",
|
||||
@@ -756,6 +758,7 @@ var jaDict = map[string]string{
|
||||
|
||||
// 質問箱ページ:訪問者に表示(P0)
|
||||
"question.errWrongPassword": "パスワードが正しくありません",
|
||||
"question.errPasswordLocked": "パスワードの誤入力が多すぎます。%d 分後にもう一度お試しください。",
|
||||
"question.errAskPasswordWrong": "質問用パスワードが正しくありません",
|
||||
"question.errLoginRequired": "質問箱の所有者は登録ユーザーのみ質問できるように設定しています。先にログインしてください。",
|
||||
"question.errSelfChat": "自分自身とのチャットは開始できません",
|
||||
@@ -925,6 +928,7 @@ var jaDict = map[string]string{
|
||||
"form.profile.name": "ニックネームは必須で、20文字以内である必要があります",
|
||||
"form.profile.newPassword": "新しいパスワードは30文字以内である必要があります",
|
||||
"form.profile.passwordMax": "パスワードは30文字以内である必要があります",
|
||||
"form.profile.passwordLen": "パスワードは6〜30文字で設定してください",
|
||||
"form.question.content": "質問内容を入力してください",
|
||||
"form.question.contentTooLong": "質問内容は%d文字以内にしてください",
|
||||
"form.question.receiveReplyEmail": "返信を受け取るための有効なメールアドレスを入力してください",
|
||||
|
||||
Reference in New Issue
Block a user