From bc438e59a2bd2acd8985d2772422d96744c196db Mon Sep 17 00:00:00 2001 From: Christian Provenzano <18606244+caproven@users.noreply.github.com> Date: Sun, 5 May 2024 14:39:17 -0400 Subject: [PATCH] fix: server info leakage through errors (#93) --- pkg/api/graphql/resolvers/mutations.go | 11 ++++++----- pkg/api/graphql/resolvers/query.go | 19 +++++++++++++------ pkg/api/rest/rest.go | 12 ++++++++---- pkg/errors/errors.go | 25 ++++++++++++++++++++++++- 4 files changed, 51 insertions(+), 16 deletions(-) diff --git a/pkg/api/graphql/resolvers/mutations.go b/pkg/api/graphql/resolvers/mutations.go index 6f735a9..3957ede 100644 --- a/pkg/api/graphql/resolvers/mutations.go +++ b/pkg/api/graphql/resolvers/mutations.go @@ -5,6 +5,7 @@ import ( "github.com/graph-gophers/graphql-go" "github.com/sassoftware/event-provenance-registry/pkg/epr" + eprErrors "github.com/sassoftware/event-provenance-registry/pkg/errors" "github.com/sassoftware/event-provenance-registry/pkg/message" "github.com/sassoftware/event-provenance-registry/pkg/storage" ) @@ -22,7 +23,7 @@ type MutationResolver struct { func (r *MutationResolver) CreateEvent(args struct{ Event epr.EventInput }) (graphql.ID, error) { event, err := epr.CreateEvent(r.msgProducer, r.Connection, args.Event) if err != nil { - return "", err + return "", eprErrors.SanitizeError(err) } return event.ID, nil } @@ -30,7 +31,7 @@ func (r *MutationResolver) CreateEvent(args struct{ Event epr.EventInput }) (gra func (r *MutationResolver) CreateEventReceiver(args struct{ EventReceiver epr.EventReceiverInput }) (graphql.ID, error) { eventReceiver, err := epr.CreateEventReceiver(r.msgProducer, r.Connection, args.EventReceiver) if err != nil { - return "", err + return "", eprErrors.SanitizeError(err) } return eventReceiver.ID, nil } @@ -38,7 +39,7 @@ func (r *MutationResolver) CreateEventReceiver(args struct{ EventReceiver epr.Ev func (r *MutationResolver) CreateEventReceiverGroup(args struct{ EventReceiverGroup epr.EventReceiverGroupInput }) (graphql.ID, error) { eventReceiverGroup, err := epr.CreateEventReceiverGroup(r.msgProducer, r.Connection, args.EventReceiverGroup) if err != nil { - return "", err + return "", eprErrors.SanitizeError(err) } return eventReceiverGroup.ID, nil } @@ -47,7 +48,7 @@ func (r *MutationResolver) SetEventReceiverGroupEnabled(args struct{ ID graphql. err := storage.SetEventReceiverGroupEnabled(r.Connection.Client, args.ID, true) if err != nil { slog.Error("error setting event receiver group enabled", "error", err, "id", args.ID) - return "", err + return "", eprErrors.SanitizeError(err) } slog.Info("updated", "eventReceiverGroupEnabled", args.ID) return args.ID, nil @@ -57,7 +58,7 @@ func (r *MutationResolver) SetEventReceiverGroupDisabled(args struct{ ID graphql err := storage.SetEventReceiverGroupEnabled(r.Connection.Client, args.ID, false) if err != nil { slog.Error("error setting event receiver group disabled", "error", err, "id", args.ID) - return "", err + return "", eprErrors.SanitizeError(err) } slog.Info("updated", "eventReceiverGroupDisabled", args.ID) return args.ID, nil diff --git a/pkg/api/graphql/resolvers/query.go b/pkg/api/graphql/resolvers/query.go index a89f320..a6c1b7f 100644 --- a/pkg/api/graphql/resolvers/query.go +++ b/pkg/api/graphql/resolvers/query.go @@ -2,6 +2,7 @@ package resolvers import ( "github.com/graph-gophers/graphql-go" + eprErrors "github.com/sassoftware/event-provenance-registry/pkg/errors" "github.com/sassoftware/event-provenance-registry/pkg/storage" ) @@ -10,25 +11,31 @@ type QueryResolver struct { } func (r *QueryResolver) Events(args struct{ Event FindEventInput }) ([]storage.Event, error) { - return storage.FindEvent(r.Connection.Client, args.Event.toMap()) + events, err := storage.FindEvent(r.Connection.Client, args.Event.toMap()) + return events, eprErrors.SanitizeError(err) } func (r *QueryResolver) EventReceivers(args struct{ EventReceiver FindEventReceiverInput }) ([]storage.EventReceiver, error) { - return storage.FindEventReceiver(r.Connection.Client, args.EventReceiver.toMap()) + receivers, err := storage.FindEventReceiver(r.Connection.Client, args.EventReceiver.toMap()) + return receivers, eprErrors.SanitizeError(err) } func (r *QueryResolver) EventReceiverGroups(args struct{ EventReceiverGroup FindEventReceiverGroupInput }) ([]storage.EventReceiverGroup, error) { - return storage.FindEventReceiverGroup(r.Connection.Client, args.EventReceiverGroup.toMap()) + groups, err := storage.FindEventReceiverGroup(r.Connection.Client, args.EventReceiverGroup.toMap()) + return groups, eprErrors.SanitizeError(err) } func (r *QueryResolver) EventsByID(args struct{ ID graphql.ID }) ([]storage.Event, error) { - return storage.FindEventByID(r.Connection.Client, args.ID) + events, err := storage.FindEventByID(r.Connection.Client, args.ID) + return events, eprErrors.SanitizeError(err) } func (r *QueryResolver) EventReceiversByID(args struct{ ID graphql.ID }) ([]storage.EventReceiver, error) { - return storage.FindEventReceiverByID(r.Connection.Client, args.ID) + receivers, err := storage.FindEventReceiverByID(r.Connection.Client, args.ID) + return receivers, eprErrors.SanitizeError(err) } func (r *QueryResolver) EventReceiverGroupsByID(args struct{ ID graphql.ID }) ([]storage.EventReceiverGroup, error) { - return storage.FindEventReceiverGroupByID(r.Connection.Client, args.ID) + groups, err := storage.FindEventReceiverGroupByID(r.Connection.Client, args.ID) + return groups, eprErrors.SanitizeError(err) } diff --git a/pkg/api/rest/rest.go b/pkg/api/rest/rest.go index 61bd45b..b7ff390 100644 --- a/pkg/api/rest/rest.go +++ b/pkg/api/rest/rest.go @@ -49,15 +49,19 @@ func handleResponse(w http.ResponseWriter, r *http.Request, data any, err error) return } - resp.Errors = []string{err.Error()} + var status int switch err.(type) { case eprErrors.MissingObjectError: - render.Status(r, http.StatusNotFound) + status = http.StatusNotFound case eprErrors.InvalidInputError: - render.Status(r, http.StatusBadRequest) + status = http.StatusBadRequest default: - render.Status(r, http.StatusInternalServerError) + status = http.StatusInternalServerError } + render.Status(r, status) + + resp.Errors = []string{eprErrors.SanitizeError(err).Error()} + slog.Error("error during request", "error", err, "url", r.URL) render.JSON(w, r, resp) } diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go index 58e5bed..b91a5f7 100644 --- a/pkg/errors/errors.go +++ b/pkg/errors/errors.go @@ -1,6 +1,9 @@ package errors -import "fmt" +import ( + "errors" + "fmt" +) type MissingObjectError struct { Msg string @@ -17,3 +20,23 @@ type InvalidInputError struct { func (e InvalidInputError) Error() string { return fmt.Sprintf("invalid input: %s", e.Msg) } + +func SanitizeError(err error) error { + if err == nil { + return nil + } + + isServerErr := false + switch err.(type) { + case MissingObjectError: + case InvalidInputError: + default: + isServerErr = true + } + + if isServerErr { + // don't expose server internals + err = errors.New("internal server error") + } + return err +}