samples/restApi: pre-parse templates (gosec G708 hardening)#124
Open
randomizedcoder wants to merge 1 commit into
Open
samples/restApi: pre-parse templates (gosec G708 hardening)#124randomizedcoder wants to merge 1 commit into
randomizedcoder wants to merge 1 commit into
Conversation
ec5064f to
f8a7d95
Compare
5 tasks
…ction
printer() previously accepted `templ string` and parsed it inline, which
gosec correctly flags as a server-side template injection (G708): if any
future caller ever wires HTTP input into templ, that's RCE.
Refactor so every template is parsed once at package init into a
package-level *template.Template, and tighten printer's signature to
accept *template.Template. The function can no longer accept a free-form
string, so the taint source is closed at the type level. Same pattern
for processPrint + processInfoTmpl.
Adds table-driven tests under samples/restApi/handlers/utils_test.go
covering positive, negative, boundary, corner, and attacker categories.
The attacker cases verify that values containing {{ ... }} in stats
fields are rendered as data, NOT re-interpreted as template directives.
Drive-by: modernize DevicesUuids loop from `for i := uint(0); i < count; i++`
to `for i := range count` (Go 1.22+ rangeint).
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: randomizedcoder <dave.seddon.ca@gmail.com>
f8a7d95 to
3ce7bad
Compare
5 tasks
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.
Hi 👋
We were running some static analysis over a fork of this repo (golangci-lint + gosec, tier-1 config) and gosec flagged a couple of G708 (server-side template injection) HIGH-severity findings in
samples/restApi/handlers/utils.go:The flagged statements parse a
text/templatefrom a value that gosec's taint analysis treats as attacker-reachable:Today every caller passes a package-level
conststring, so this is fragile-by-structure rather than unsafe-today. But sample code tends to get copy-pasted into production, and the next reader who wires HTTP form input intotemplgets RCE. The fix is purely structural.What this PR does
*template.Template(deviceInfoTmpl,processInfoTmpl, etc.).printer's signature fromtempl stringtotmpl *template.Template. The function can no longer accept a free-form string, so the taint source is closed at the type-system level — the compiler will reject any futureprinter(..., userInput)call.processPrint(now usesprocessInfoTmpl).printercall sites inbyIds.goandbyUuids.goto pass the pre-parsed templates.Templates stay
text/template(the samples render plain-text curl-style output, not HTML) — no escaping behavior changes.TDD + table-driven tests
Added
samples/restApi/handlers/utils_test.go(18 cases across two table-driven tests) covering five categories per the test struct'scategorytag:positivenegativeboundarycornerattacker{{ ... }}template syntax embedded in stats data renders as data, NOT re-evaluated as a template — this is the core security assertion that the pre-parsed template doesn't re-parse the payloadTests are GPU-less (
httptest.NewRecorderonly, nodcgm.Init), so they run on any CI runner. House style followspkg/dcgm/diag_test.go:stretchr/testify/assert+t.Run(tt.name, ...)subtests.Why this is low risk
go build ./samples/...).go vet,gofmt, and the newgo test ./samples/restApi/handlers/...all green.DevicesUuids()loop modernized fromfor i := uint(0); i < count; i++tofor i := range count(Go 1.22+ rangeint, since go.mod isgo 1.23). Happy to split this out if you'd prefer a single-concern PR.Cheers, and thanks for go-dcgm — it's been a great library to work with.
Test plan
go build ./samples/restApi/...go test -v -count=1 ./samples/restApi/handlers/...— 18/18 passgo vet ./samples/restApi/...gofmt -l samples/restApi/handlers/— empty🤖 Generated with Claude Code