diff --git a/backend/internal/deployment/model.go b/backend/internal/deployment/model.go index 3bf9c8b..855c5d3 100644 --- a/backend/internal/deployment/model.go +++ b/backend/internal/deployment/model.go @@ -106,6 +106,13 @@ func ResolveServerPaths(server Server, domainName, certificateType string) (Serv if err != nil { return Server{}, err } + if err := validateDeploymentPaths([]remoteFile{ + {path: server.CertificatePath}, + {path: server.CertificateChainPath}, + {path: server.PrivateKeyPath}, + }); err != nil { + return Server{}, err + } return server, nil } @@ -130,7 +137,7 @@ func resolveServerPathTemplate(label, value string, replacer *strings.Replacer) if !strings.HasPrefix(cleaned, "/") { return "", fmt.Errorf("%s必须是绝对路径", label) } - return resolved, nil + return cleaned, nil } func (s Server) Validate() error { diff --git a/backend/internal/deployment/model_test.go b/backend/internal/deployment/model_test.go index 6125ea7..a449e80 100644 --- a/backend/internal/deployment/model_test.go +++ b/backend/internal/deployment/model_test.go @@ -75,6 +75,28 @@ func TestResolveServerPathsRejectsRelativePath(t *testing.T) { } } +func TestResolveServerPathsCanonicalizesPathAndRejectsDuplicate(t *testing.T) { + server := testServer("one") + server.CertificatePath = "/ssl/example/../example/cert.pem" + resolved, err := ResolveServerPaths(server, "example.com", "single") + if err != nil { + t.Fatalf("path normalization failed: %v", err) + } + if resolved.CertificatePath != "/ssl/example/cert.pem" { + t.Fatalf("unexpected normalized path: %s", resolved.CertificatePath) + } + + server = testServer("one") + server.CertificatePath = "/ssl/example/../example/cert.pem" + server.PrivateKeyPath = "/ssl/example/../example/cert.pem" + if _, err := ResolveServerPaths(server, "example.com", "single"); err == nil { + FatalUnexpectedPath(t) + } +} +func FatalUnexpectedPath(t *testing.T) { + t.Helper() + t.Fatal("duplicate path accepted") +} func TestServerRejectsPasswordStyleOrUnsafeConfiguration(t *testing.T) { server := testServer("one") server.PrivateKeyRef = ""