fix: preserve JSON types when extracting integration variables#3820
fix: preserve JSON types when extracting integration variables#3820
Conversation
The Extract function now returns map[string]any instead of map[string]string,
preserving JSON types (objects, arrays, numbers, booleans) instead of
converting them to Go string representations via fmt.Sprintf("%v", val).
Previously, a JSON payload like {"data":{"id":2,"name":"test"}} would produce
the environment variable data="map[id:2 name:test]" (Go's internal format).
Now it is correctly forwarded as a proper JSON dict {"id":2,"name":"test"}.
Also adds TestGetTaskDefinition_JSONObjectInEnv and
TestExtract_JSONBody_ObjectPreservedAsMap to verify the fix.
Agent-Logs-Url: https://github.com/semaphoreui/semaphore/sessions/5bb1f79a-b7b0-4c5a-a224-4fc41c67e920
Co-authored-by: fiftin <914224+fiftin@users.noreply.github.com>
There was a problem hiding this comment.
Security review (automation)
Scope: api/integration.go change to Extract return type map[string]any and preserve native JSON values from gojsonq instead of fmt.Sprintf("%v", val); related tests.
Prior threads: Cleaned up previous automation review artifacts; re-validated against the current diff.
Findings: None at medium or higher confidence.
Rationale (summary): Webhook payload is still only accepted after the integration’s configured auth (HMAC, token, basic, or none) and optional matchers. The change only alters how parsed JSON is represented when merging into task environment (json.Marshal/Unmarshal) and task params (ExtractParams marshals Params then json.Unmarshal into typed structs). Nested maps/slices are handled by encoding/json as before for env merging; scalars now round-trip as JSON booleans/numbers instead of strings, which avoids json.Unmarshal failures into typed task-param structs rather than introducing a new trust boundary.
Slack summary: PR #3820 security pass — no medium/high/critical issues. Integration webhook extraction now keeps native JSON types for env/task params; auth model unchanged; no new injection or authz bypass identified in the diff.
Sent by Cursor Automation: Find vulnerabilities


When extracting JSON body values in integrations, all values were converted to strings via
fmt.Sprintf("%v", val), causing JSON objects to be passed as Go's internal representation (map[id:2 name:test]) instead of proper JSON structures.Changes
api/integration.go: ChangedExtractreturn type frommap[string]stringtomap[string]any, dropping thefmt.Sprintf("%v", val)coercion so gojsonq values are passed through as native Go types — objects asmap[string]interface{}, arrays as[]interface{}, numbers asfloat64, booleans asboolapi/integration_test.go: Updated type assertions to match correct native types; addedTestExtract_JSONBody_ObjectPreservedAsMapandTestGetTaskDefinition_JSONObjectInEnvcovering the reported scenario end-to-endBefore / After