Files
tamabox/internal/route/assets/assets.go
T
tamakyi 0318ba81b4 feat(autoban): 封禁响应体改成一张 403 图片
被封禁来源访问任何路径时,原来只回 13 字节的 "403 Forbidden":既没有信息量,
人肉访问(尤其是共享出口被连累的误封)时看着像站点挂了;扫描/爆破脚本也常靠
读这行明文确认「自己已被拦」。

改为返回一张 256×256 的 webp(约 8.6 KB,画面写着 403 Forbidden),状态码不变:
- 图片用 //go:embed 编进二进制,不依赖外部 URL、不占公开路径;
- 显式给 Content-Length(8 KB 超过 Go 的 2 KB 写缓冲,不设会退回 chunked);
- Cache-Control: no-store —— 中间层缓存 403 没有意义,还会让解封后的响应继续命中;
- HEAD 只回头不写 body;
- 放在 internal/route/assets/ 而不是 static/:static 下的东西有可公开访问的 URL,
  等于多一个指纹入口。

注意链接:给的 R2 预签名地址 X-Amz-Expires=604800(7 天),热链到期就会挂,
所以是把字节取回来打包,而不是重定向或代理。

测试:
- TestWriteBanned:状态码 403、image/webp、Content-Length 与内嵌字节数一致、
  body 前 12 字节是 RIFF/WEBP(防止被换成 HTML 或明文这类回归);
- TestWriteBannedHead:HEAD 无 body 但有 Content-Length;
- 原 TestHoneypotBansEvenWhenAutoBanDisabled 里断言 "403 Forbidden" 明文的用例
  改为断言 image/webp 与体积。
变异验证:把 writeBanned 改回写明文 + text/plain,两条用例均按预期变红。
2026-10-23 15:04:13 +08:00

21 lines
992 B
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package assets 存放「必须由服务端直接吐出」的二进制资源。
//
// 为什么不放 static/:static 下的东西由静态文件中间件按 URL 提供,
// 而这里的图片只该出现在 403 响应体里 —— 不该有一个能直接访问的公开路径
// (否则被 ban 的人可以先抓一张「解禁图」,也等于多一个指纹入口)。
package assets
import _ "embed"
// BannedImage 是被封禁来源访问任何路径时返回的图(256×256 webp,约 8.6 KB)。
//
// 换成图片的动机:被封之后每次请求都只拿到 13 字节的 "403 Forbidden",
// 既没有信息量,也让人误以为是站点挂了。这张图明确写着 403 Forbidden,
// 人一看就懂,而状态码仍然是 403 —— 语义没变,只换了 body。
//
// 想替换:直接覆盖同目录的 403.webp 后重新编译(go:embed 是编译期打包的,
// 不需要重启之外的操作)。
//
//go:embed 403.webp
var BannedImage []byte