26.9(安全审计修复版)
Go 1.27.1 (Gin+GORM) + Vue 3 文件快传服务: - 安全审计全部修复(docs/security-audit-2026-09-05.md): bcrypt 密码哈希与自动升级、presign 直传服务端大小/内容校验、 全局请求体上限、依赖升级(govulncheck 0 命中)、janitor 后台清理、 管理端审计动作落库、/admin CORS 收紧、通知内容白名单净化、 会话默认 7 天、限流缓存故障降级、robots.txt 端点等 - 前端:取件链接复制修复(不再重复拼接提取码)、markdown 净化器加固 - Redis 支持库号(FCB_REDIS_DB / redis://…/db URL) - 文档:docs/api/* 与 openapi.yaml 同步最新行为(robots.txt、 提码 5 位起、chunk 32MiB 上限、admin 审计动作等) 验证:gofmt/go vet/go test 全绿;二进制端到端冒烟通过
This commit is contained in:
@@ -0,0 +1,74 @@
|
||||
package storage
|
||||
|
||||
import (
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"io"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// TestSanitizePath 校验路径穿越防护。
|
||||
func TestSanitizePath(t *testing.T) {
|
||||
cases := []struct {
|
||||
in string
|
||||
ok bool
|
||||
out string
|
||||
}{
|
||||
{"2025/08/uuid.zip", true, "2025/08/uuid.zip"},
|
||||
{"/2025/08/uuid.zip", true, "2025/08/uuid.zip"},
|
||||
{"a\\b\\c.txt", true, "a/b/c.txt"},
|
||||
{"../etc/passwd", false, ""},
|
||||
{"a/../../b", false, ""},
|
||||
{"..", false, ""},
|
||||
{"", false, ""},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
got, ok := SanitizePath(tc.in)
|
||||
if ok != tc.ok || (ok && got != tc.out) {
|
||||
t.Errorf("SanitizePath(%q) = (%q, %v), want (%q, %v)", tc.in, got, ok, tc.out, tc.ok)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestSanitizeFileName 校验文件名清理。
|
||||
func TestSanitizeFileName(t *testing.T) {
|
||||
cases := []struct{ in, want string }{
|
||||
{"hello world.zip", "hello_world.zip"},
|
||||
{"/path/to/file.txt", "file.txt"},
|
||||
{"a<b>:c?.mp4", "a_b_c_.mp4"}, // 连续下划线压缩,对齐参考 re.sub(r"_+", "_")
|
||||
{"", "unnamed_file"},
|
||||
{"__..__", "unnamed_file"},
|
||||
}
|
||||
for _, tc := range cases {
|
||||
if got := SanitizeFileName(tc.in); got != tc.want {
|
||||
t.Errorf("SanitizeFileName(%q) = %q, want %q", tc.in, got, tc.want)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TestChunkPartPath 校验分片路径约定。
|
||||
func TestChunkPartPath(t *testing.T) {
|
||||
got := ChunkPartPath("2025/08/uuid.zip", "upload-1", 3)
|
||||
want := "2025/08/chunks/upload-1/3.part"
|
||||
if got != want {
|
||||
t.Errorf("ChunkPartPath = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestChunkDir 校验分片目录约定。
|
||||
func TestChunkDir(t *testing.T) {
|
||||
got := ChunkDir("2025/08/uuid.zip", "upload-1")
|
||||
want := "2025/08/chunks/upload-1/uuid.zip"
|
||||
if got != want {
|
||||
t.Errorf("ChunkDir = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSHA256Helper 辅助:确认 sha256 用法一致(合并校验依赖)。
|
||||
func TestSHA256Helper(t *testing.T) {
|
||||
h := sha256.Sum256([]byte("abc"))
|
||||
if got := hex.EncodeToString(h[:]); got != "ba7816bf8f01cfea414140de5dae2223b00361a396177a9cb410ff61f20015ad" {
|
||||
t.Errorf("sha256(abc) = %s", got)
|
||||
}
|
||||
_ = io.EOF
|
||||
}
|
||||
Reference in New Issue
Block a user