security: disable $ENV in tool response filters and sync validation c… · github/gh-aw-mcpg@49a7912 · GitHub
Skip to content

Commit 49a7912

Browse files
authored
security: disable $ENV in tool response filters and sync validation compile options (#7208)
Tool response filters compiled without `WithEnvironLoader` could expose environment variables (including `GITHUB_TOKEN`) if a filter referenced `$ENV`. Validation also compiled with different options than the runtime path, meaning `$ENV`-referencing filters would pass validation but behave differently at runtime. ## Changes - **`internal/middleware/jqschema.go`** — Add `gojq.WithEnvironLoader(func() []string { return nil })` to `CompileToolResponseFilter`, matching the existing guard on the `walk_schema` path: ```go code, err := gojq.Compile(query, gojq.WithEnvironLoader(func() []string { return nil }), // explicitly disable $ENV access (defense-in-depth) ) ``` - **`internal/config/validation.go`** — Apply the same `WithEnvironLoader` option in `validateToolResponseFilters` so validation accurately predicts runtime behavior. Previously a filter using `$ENV` would pass validation but silently return `null`/`{}` for `$ENV` references at runtime. - **`internal/middleware/jqschema.go`** — Improve the multiple-results error message to guide admins toward the correct fix: ``` // Before: "tool response filter returned multiple results, first=... extra=..." // After: "tool response filter returned multiple results — use array form ([.a, .b]) to combine outputs into a single value; first=... extra=..." ``` - **`internal/middleware/jqschema_coverage_test.go`** — Add `TestCompileToolResponseFilter_EnvDisabled` which runs a `$ENV`-referencing filter through the compiled code object directly and asserts `$ENV` resolves to `{}`, not the real process environment.
2 parents 38a0ad4 + 709b209 commit 49a7912

3 files changed

Lines changed: 32 additions & 3 deletions

File tree

internal/config/validation.go

Lines changed: 3 additions & 1 deletion

internal/middleware/jqschema.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,7 @@ func runJqCode(
253253

254254
if opts.CheckMultipleResults {
255255
if extra, ok := iter.Next(); ok {
256-
return nil, fmt.Errorf("%s returned multiple results, first=%T extra=%T", errPrefix, v, extra)
256+
return nil, fmt.Errorf("%s returned multiple results — use array form ([.a, .b]) to combine outputs into a single value; first=%T extra=%T", errPrefix, v, extra)
257257
}
258258
}
259259

@@ -279,7 +279,9 @@ func CompileToolResponseFilter(filter string) (*gojq.Code, error) {
279279
return nil, fmt.Errorf("failed to parse tool response filter: %w", err)
280280
}
281281

282-
code, err := gojq.Compile(query)
282+
code, err := gojq.Compile(query,
283+
gojq.WithEnvironLoader(func() []string { return nil }), // explicitly disable $ENV access (defense-in-depth)
284+
)
283285
if err != nil {
284286
return nil, fmt.Errorf("failed to compile tool response filter: %w", err)
285287
}

internal/middleware/jqschema_coverage_test.go

Lines changed: 25 additions & 0 deletions

0 commit comments

Comments
 (0)