From 51459d39094d01ae78c0fc7a212b78ed2030078a Mon Sep 17 00:00:00 2001 From: xuans Date: Mon, 31 Aug 2026 02:40:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E8=AF=81=E4=B9=A6=E9=83=A8?= =?UTF-8?q?=E7=BD=B2=E6=8A=A5=E5=91=8A=E9=94=99=E8=AF=AF=E8=84=B1=E6=95=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/internal/httpapi/certificate_api.go | 2 + .../internal/httpapi/certificate_api_test.go | 67 +++++++++++++++++++ 2 files changed, 69 insertions(+) diff --git a/backend/internal/httpapi/certificate_api.go b/backend/internal/httpapi/certificate_api.go index 3585041..62b28ab 100644 --- a/backend/internal/httpapi/certificate_api.go +++ b/backend/internal/httpapi/certificate_api.go @@ -112,6 +112,7 @@ func (s *Server) deployCertificateCurrent(c *gin.Context) { return } result, report, err := s.deployCertificate(c.Request.Context(), strings.TrimSpace(c.Param("id"))) + report = sanitizeDeploymentReport(report) response := gin.H{"certificate": result, "deployment": report} if err != nil { if s.logger != nil { @@ -137,6 +138,7 @@ func (s *Server) importCertificateFiles(c *gin.Context) { } defer cleanup() result, report, err := s.importCertificate(c.Request.Context(), request) + report = sanitizeDeploymentReport(report) response := gin.H{"certificate": result, "deployment": report} if err != nil { if s.logger != nil { diff --git a/backend/internal/httpapi/certificate_api_test.go b/backend/internal/httpapi/certificate_api_test.go index 4f0f22c..1c57639 100644 --- a/backend/internal/httpapi/certificate_api_test.go +++ b/backend/internal/httpapi/certificate_api_test.go @@ -237,3 +237,70 @@ func TestCertificateImportAPIRejectsInvalidPathJSON(t *testing.T) { } } } + +func TestCertificateDeployAPISanitizesReportDetails(t *testing.T) { + server := New(Dependencies{ + Config: readyTestConfig(t.TempDir()), + Repository: &stubDomainRepository{}, + DeployCertificate: func(context.Context, string) (certificate.IssueResult, deployment.Report, error) { + return certificate.IssueResult{}, deployment.Report{ + Total: 1, + Failed: 1, + Status: "failed", + Results: []deployment.Result{{ + ServerID: "server-1", + Server: "生产服务器", + Status: "failed", + Message: "上传远程证书失败:/etc/nginx/private/key.pem: permission denied", + }}, + }, errors.New("private-key-secret-path") + }, + }) + response := httptest.NewRecorder() + serveAdminHTTP(server, response, httptest.NewRequest(http.MethodPost, "/api/v1/domains/domain-1/deploy", nil)) + body := response.Body.String() + if !strings.Contains(body, "证书部署失败") { + t.Fatalf("证书部署失败响应缺少稳定错误:%s", body) + } + if strings.Contains(body, "/etc/nginx/private/key.pem") || strings.Contains(body, "permission denied") { + t.Fatalf("证书部署响应泄露了报告明细:%s", body) + } + if !strings.Contains(body, "生产服务器") || !strings.Contains(body, "server-1") { + t.Fatalf("证书部署响应缺少安全的服务器信息:%s", body) + } +} + +func TestCertificateImportAPISanitizesReportDetails(t *testing.T) { + server := New(Dependencies{ + Config: readyTestConfig(t.TempDir()), + Repository: &stubDomainRepository{}, + ImportCertificate: func(context.Context, certificate.ImportRequest) (certificate.IssueResult, deployment.Report, error) { + return certificate.IssueResult{}, deployment.Report{ + Total: 1, + Failed: 1, + Status: "failed", + Results: []deployment.Result{{ + ServerID: "server-1", + Server: "生产服务器", + Status: "failed", + Message: "上传远程证书失败:/etc/nginx/private/key.pem: permission denied", + }}, + }, errors.New("private-key-secret-path") + }, + }) + body := `{"certificate_path":"/ssl/cert.pem","private_key_path":"/ssl/key.pem"}` + request := httptest.NewRequest(http.MethodPost, "/api/v1/domains/domain-1/certificate/import", strings.NewReader(body)) + request.Header.Set("Content-Type", "application/json") + response := httptest.NewRecorder() + serveAdminHTTP(server, response, request) + responseBody := response.Body.String() + if !strings.Contains(responseBody, "证书导入失败") { + t.Fatalf("证书导入失败响应缺少稳定错误:%s", responseBody) + } + if strings.Contains(responseBody, "/etc/nginx/private/key.pem") || strings.Contains(responseBody, "permission denied") { + t.Fatalf("证书导入响应泄露了报告明细:%s", responseBody) + } + if !strings.Contains(responseBody, "生产服务器") || !strings.Contains(responseBody, "server-1") { + t.Fatalf("证书导入响应缺少安全的服务器信息:%s", responseBody) + } +}