Files
xlgo-core/middleware/cors_internal_test.go
2026-07-14 10:24:10 +08:00

95 lines
3.3 KiB
Go
Raw Permalink 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 middleware
import "testing"
// 回归 C7a:通配符子域匹配必须锚定真实子域边界,拒绝后缀相同但非子域的域名。
// 旧实现 strings.HasSuffix(origin, domain) 接受 notexample.com / evil-example.com。
func TestMatchOriginWildcardBoundary(t *testing.T) {
cases := []struct {
name string
origin string
ao string
want bool
}{
// 精确匹配
{"exact", "https://example.com", "https://example.com", true},
{"exact with port", "https://example.com:8443", "https://example.com:8443", true},
{"exact mismatch", "https://example.com", "https://other.com", false},
// 通配子域 *.example.com
{"subdomain ok", "https://a.example.com", "*.example.com", true},
{"deep subdomain ok", "https://a.b.example.com", "*.example.com", true},
{"subdomain with port ok", "https://a.example.com:3000", "*.example.com", true},
{"apex not matched by wildcard", "https://example.com", "*.example.com", false},
// C7a 核心:后缀相同但非真实子域必须拒绝
{"notexample.com rejected", "https://notexample.com", "*.example.com", false},
{"evil-example.com rejected", "https://evil-example.com", "*.example.com", false},
{"villainexample.com rejected", "https://villainexample.com", "*.example.com", false},
// 端口/协议不同的 origin host 仍按 host 判断
{"http subdomain ok", "http://a.example.com", "*.example.com", true},
// 通配仅匹配 host,scheme 不同的精确配置不被通配覆盖
{"different scheme exact not wildcard", "http://example.com", "https://example.com", false},
// 边界
{"empty origin", "", "*.example.com", false},
{"empty ao", "https://a.example.com", "", false},
{"malformed origin", "://:bad", "*.example.com", false},
}
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
got := matchOrigin(c.origin, c.ao)
if got != c.want {
t.Errorf("matchOrigin(%q, %q) = %v, want %v", c.origin, c.ao, got, c.want)
}
})
}
}
// 回归 C7a:通配大小写不敏感(host 归一化为小写比较)。
func TestMatchOriginCaseInsensitive(t *testing.T) {
if !matchOrigin("https://A.Example.COM", "*.example.com") {
t.Error("matchOrigin should be case-insensitive on host")
}
}
// 回归 C7atrailing dot FQDNa.example.com.)应等同 a.example.com 被接受(功能正确性)。
func TestMatchOriginTrailingDot(t *testing.T) {
if !matchOrigin("https://a.example.com.", "*.example.com") {
t.Error("trailing-dot subdomain should match wildcard")
}
if !matchOrigin("https://a.example.com", "*.example.com.") {
t.Error("trailing-dot wildcard should match plain subdomain")
}
}
// 回归 C7bisLocalhostOrigin 仅允许 localhost/127.0.0.1/::1,拒绝任意其他来源。
func TestIsLocalhostOrigin(t *testing.T) {
allowed := []string{
"http://localhost:3000",
"http://localhost",
"http://127.0.0.1:8080",
"http://127.0.0.1",
"http://[::1]:4000",
"http://[::1]",
}
for _, o := range allowed {
if !isLocalhostOrigin(o) {
t.Errorf("isLocalhostOrigin(%q) = false, want true", o)
}
}
denied := []string{
"https://evil.com",
"https://localhost.evil.com", // 后缀含 localhost 但非 localhost host
"https://notlocalhost.com",
"https://example.com",
"",
"://bad",
}
for _, o := range denied {
if isLocalhostOrigin(o) {
t.Errorf("isLocalhostOrigin(%q) = true, want false", o)
}
}
}