From fb06ae00c127680feaa0888519352ee12d883dde Mon Sep 17 00:00:00 2001 From: rcourtman Date: Wed, 4 Feb 2026 12:18:40 +0000 Subject: [PATCH] Harden config export/import validation --- internal/api/security_regression_test.go | 38 ++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/internal/api/security_regression_test.go b/internal/api/security_regression_test.go index e978cf9d2..8fbfa34c0 100644 --- a/internal/api/security_regression_test.go +++ b/internal/api/security_regression_test.go @@ -1402,6 +1402,44 @@ func TestConfigImportRequiresSettingsWriteScope(t *testing.T) { } } +func TestConfigExportRejectsShortPassphrase(t *testing.T) { + rawToken := "config-export-pass-token-123.12345678" + record := newTokenRecord(t, rawToken, []string{config.ScopeSettingsRead}, nil) + cfg := newTestConfigWithTokens(t, record) + router := NewRouter(cfg, nil, nil, nil, nil, "1.0.0") + + req := httptest.NewRequest(http.MethodPost, "/api/config/export", strings.NewReader(`{"passphrase":"short"}`)) + req.RemoteAddr = "127.0.0.1:1234" + req.Header.Set("X-API-Token", rawToken) + rec := httptest.NewRecorder() + router.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusBadRequest { + t.Fatalf("expected 400 for short passphrase, got %d", rec.Code) + } + if !strings.Contains(rec.Body.String(), "Passphrase must be at least 12 characters") { + t.Fatalf("expected passphrase length error, got %q", rec.Body.String()) + } +} + +func TestConfigImportRejectsMissingData(t *testing.T) { + rawToken := "config-import-data-token-123.12345678" + record := newTokenRecord(t, rawToken, []string{config.ScopeSettingsWrite}, nil) + cfg := newTestConfigWithTokens(t, record) + router := NewRouter(cfg, nil, nil, nil, nil, "1.0.0") + + req := httptest.NewRequest(http.MethodPost, "/api/config/import", strings.NewReader(`{"passphrase":"long-enough-passphrase","data":""}`)) + req.RemoteAddr = "127.0.0.1:1234" + req.Header.Set("X-API-Token", rawToken) + rec := httptest.NewRecorder() + router.Handler().ServeHTTP(rec, req) + if rec.Code != http.StatusBadRequest { + t.Fatalf("expected 400 for missing data, got %d", rec.Code) + } + if !strings.Contains(rec.Body.String(), "Import data is required") { + t.Fatalf("expected import data error, got %q", rec.Body.String()) + } +} + func TestConfigExportRequiresAuthInAPIMode(t *testing.T) { record := newTokenRecord(t, "config-export-auth-token", []string{config.ScopeSettingsRead}, nil) cfg := newTestConfigWithTokens(t, record)