From a6fc1a00144e332712b37d2d6fc7f7a0b3b2a463 Mon Sep 17 00:00:00 2001 From: Chad Billman Date: Wed, 21 May 2025 14:14:30 -0400 Subject: [PATCH] Allow decodeEventUpload to decode json with strings Santa sometimes sends file_bundle_hash_millis enclosed in quotes --- go.mod | 1 + go.sum | 2 + moroz/svc_upload_event.go | 3 +- moroz/svc_upload_event_test.go | 77 ++++++++++++++++++++++++++++++++++ 4 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 moroz/svc_upload_event_test.go diff --git a/go.mod b/go.mod index 9977b8f..d89e5d3 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( require ( github.com/go-logfmt/logfmt v0.3.0 // indirect github.com/go-stack/stack v1.7.0 // indirect + github.com/goccy/go-yaml v1.17.1 // indirect github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f // indirect github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 // indirect golang.org/x/net v0.0.0-20180124060956-0ed95abb35c4 // indirect diff --git a/go.sum b/go.sum index bfacc4e..665dc9b 100644 --- a/go.sum +++ b/go.sum @@ -6,6 +6,8 @@ github.com/go-logfmt/logfmt v0.3.0 h1:8HUsc87TaSWLKwrnumgC8/YconD2fJQsRJAsWaPg2i github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-stack/stack v1.7.0 h1:S04+lLfST9FvL8dl4R31wVUC/paZp/WQZbLmUgWboGw= github.com/go-stack/stack v1.7.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/goccy/go-yaml v1.17.1 h1:LI34wktB2xEE3ONG/2Ar54+/HJVBriAGJ55PHls4YuY= +github.com/goccy/go-yaml v1.17.1/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f h1:9oNbS1z4rVpbnkHBdPZU4jo9bSmrLpII768arSyMFgk= github.com/gorilla/context v0.0.0-20160226214623-1ea25387ff6f/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.1 h1:KOwqsTYZdeuMacU7CxjMNYEKeBvLbxW+psodrbcEa3A= diff --git a/moroz/svc_upload_event.go b/moroz/svc_upload_event.go index f02bde6..4b201d9 100644 --- a/moroz/svc_upload_event.go +++ b/moroz/svc_upload_event.go @@ -11,6 +11,7 @@ import ( "time" "github.com/go-kit/kit/endpoint" + "github.com/goccy/go-yaml" "github.com/pkg/errors" "github.com/groob/moroz/santa" @@ -75,7 +76,7 @@ func decodeEventUpload(ctx context.Context, r *http.Request) (interface{}, error // decode the JSON into individual log events. var eventPayload santa.EventUploadRequest - if err := json.NewDecoder(zr).Decode(&eventPayload); err != nil { + if err := yaml.NewDecoder(zr).Decode(&eventPayload); err != nil { return nil, errors.Wrap(err, "decoding event upload request json") } diff --git a/moroz/svc_upload_event_test.go b/moroz/svc_upload_event_test.go new file mode 100644 index 0000000..240c863 --- /dev/null +++ b/moroz/svc_upload_event_test.go @@ -0,0 +1,77 @@ +package moroz + +import ( + "bytes" + "compress/zlib" + "context" + "net/http" + "testing" + + "github.com/gorilla/mux" +) + +func TestDecodeEventUpload(t *testing.T) { + tests := []struct { + name string + inputJSON string + expectedID string + expectedError bool + }{ + { + name: "Valid JSON", + inputJSON: `{"events":[{"file_sha256":"abc123","execution_time": 123456789 ,"some_field":"value"}]}`, + expectedID: "serial_number", + expectedError: false, + }, + { + name: "Valid JSON with file_bundle_hash_millis as string", + inputJSON: `{"events":[{"file_bundle_hash_millis":"114"}] ,"machine_id": "serial_number"}`, + expectedID: "serial_number", + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + var buf bytes.Buffer + zw := zlib.NewWriter(&buf) + _, err := zw.Write([]byte(tt.inputJSON)) + if err != nil { + t.Fatalf("failed to write compressed data: %v", err) + } + zw.Close() + + req, err := http.NewRequest("POST", "/v1/santa/eventupload/serial_number", &buf) + if err != nil { + t.Fatalf("failed to create request: %v", err) + } + + vars := map[string]string{"id": "serial_number"} + req = mux.SetURLVars(req, vars) + + req.Header.Set("Content-Encoding", "deflate") + + result, err := decodeEventUpload(context.Background(), req) + if tt.expectedError { + if err == nil { + t.Errorf("expected an error but got none") + } + return + } + + if err != nil { + t.Errorf("unexpected error: %v", err) + return + } + + reqResult, ok := result.(eventRequest) + if !ok { + t.Fatalf("expected eventRequest, got %T", result) + } + + if reqResult.MachineID != tt.expectedID { + t.Errorf("expected MachineID %q, got %q", tt.expectedID, reqResult.MachineID) + } + }) + } +}