security: 配置 Provider 出站端口白名单 (#55)

This commit is contained in:
ila
2026-08-25 11:59:53 +08:00
parent 841d396cdf
commit b0ecbabdf0
10 changed files with 134 additions and 14 deletions
+6 -1
View File
@@ -17,6 +17,7 @@ import (
"git.ilapage.cn/OPC/chorus/admin/common/database"
common "git.ilapage.cn/OPC/chorus/admin/common/middleware"
ext "git.ilapage.cn/OPC/chorus/admin/config"
sharedconfig "git.ilapage.cn/OPC/chorus/internal/config"
safehttp "git.ilapage.cn/OPC/chorus/internal/platform/http"
"github.com/gin-gonic/gin"
"github.com/go-admin-team/go-admin-core/config/source/file"
@@ -100,7 +101,11 @@ func serviceConfigFromEnvironment(lookup func(string) (string, bool)) (configure
if err != nil {
return configuredService{}, errors.New("CHORUS_PROVIDER_MAX_RESPONSE_BYTES must be a positive integer")
}
client, err := safehttp.New(safehttp.Config{Timeout: timeout, MaxRedirects: 3})
allowedPorts, err := sharedconfig.ParseProviderAllowedPorts(read("CHORUS_PROVIDER_ALLOWED_PORTS"))
if err != nil {
return configuredService{}, errors.New("CHORUS_PROVIDER_ALLOWED_PORTS must be a comma-separated list of ports")
}
client, err := safehttp.New(safehttp.Config{Timeout: timeout, MaxRedirects: 3, AllowedPorts: allowedPorts})
if err != nil {
return configuredService{}, errors.New("configure SSRF-safe connectivity client")
}
+29
View File
@@ -24,6 +24,35 @@ func TestServiceConfigRequiresAllExplicitConnectivityLimits(t *testing.T) {
}
}
func TestServiceConfigRejectsInvalidProviderAllowedPorts(t *testing.T) {
_, err := serviceConfigFromEnvironment(testEnvironment(map[string]string{
"CHORUS_ADMIN_ALLOW_CONNECTIVITY_PROBES": "1",
"CHORUS_ADMIN_CONNECTIVITY_COOLDOWN_SECONDS": "60",
"CHORUS_PROVIDER_HTTP_TIMEOUT_SECONDS": "10",
"CHORUS_PROVIDER_MAX_RESPONSE_BYTES": "1024",
"CHORUS_PROVIDER_ALLOWED_PORTS": "80,,443",
}))
if err == nil || !strings.Contains(err.Error(), "CHORUS_PROVIDER_ALLOWED_PORTS") {
t.Fatalf("invalid provider ports error = %v", err)
}
}
func TestServiceConfigAcceptsCustomProviderAllowedPort(t *testing.T) {
configured, err := serviceConfigFromEnvironment(testEnvironment(map[string]string{
"CHORUS_ADMIN_ALLOW_CONNECTIVITY_PROBES": "1",
"CHORUS_ADMIN_CONNECTIVITY_COOLDOWN_SECONDS": "60",
"CHORUS_PROVIDER_HTTP_TIMEOUT_SECONDS": "10",
"CHORUS_PROVIDER_MAX_RESPONSE_BYTES": "1024",
"CHORUS_PROVIDER_ALLOWED_PORTS": "80,443,8080",
}))
if err != nil {
t.Fatal(err)
}
if !configured.config.AllowConnectivityChecks || configured.config.Probe == nil {
t.Fatal("connectivity probe was not configured")
}
}
func testEnvironment(values map[string]string) func(string) (string, bool) {
return func(key string) (string, bool) {
value, ok := values[key]