Skip to content

fix: gojq module review — permissions, collision, rename, upgrade#3451

Merged
lpcox merged 4 commits intomainfrom
copilot/go-fan-review-gojq-module
Apr 9, 2026
Merged

fix: gojq module review — permissions, collision, rename, upgrade#3451
lpcox merged 4 commits intomainfrom
copilot/go-fan-review-gojq-module

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Apr 9, 2026

Addresses findings from the Go Fan gojq module review.

Security

  • Payload file permissions 06440600 — payloads may contain sensitive API responses; no reason for world-readable

Bug fix

  • generateRandomID fallback collision — when crypto/rand.Read fails, the fallback was fmt.Sprintf("fallback-%d", os.Getpid()) which is identical for every call in the same process. Added time.Now().UnixNano():
return fmt.Sprintf("fallback-%d-%d", os.Getpid(), time.Now().UnixNano())

Maintenance

  • Rename def walk(f)def walk_schema — avoids shadowing gojq's built-in walk/1. Now a zero-arity recursive def since the f parameter was never meaningfully used (always called as walk(.))
  • Upgrade github.com/itchyny/gojq v0.12.18 → v0.12.19

Tests

  • TestApplyJqSchema_SingleOutputContract — asserts the jq filter iterator yields exactly one value across multiple input shapes, documenting the invariant
  • Updated TestPayloadStorage_FilePermissions expectation to 0600

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • example.com
    • Triggering command: /tmp/go-build511967270/b514/launcher.test /tmp/go-build511967270/b514/launcher.test -test.testlogfile=/tmp/go-build511967270/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build511967270/b211/vet.cfg 6718451/b186/_pkg_.a ache/go/1.25.8/x64/src/vendor/golang.org/x/text/-Wl,--no-gc-sections x_amd64/vet . --gdwarf2 --64 x_amd64/vet (dns block)
  • invalid-host-that-does-not-exist-12345.com
    • Triggering command: /tmp/go-build511967270/b496/config.test /tmp/go-build511967270/b496/config.test -test.testlogfile=/tmp/go-build511967270/b496/testlog.txt -test.paniconexit0 -test.timeout=10m0s -o ache/go/1.25.8/x64/src/net -trimpath x_amd64/vet -p net/url -lang=go1.25 x_amd64/vet (dns block)
  • nonexistent.local
    • Triggering command: /tmp/go-build511967270/b514/launcher.test /tmp/go-build511967270/b514/launcher.test -test.testlogfile=/tmp/go-build511967270/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build511967270/b211/vet.cfg 6718451/b186/_pkg_.a ache/go/1.25.8/x64/src/vendor/golang.org/x/text/-Wl,--no-gc-sections x_amd64/vet . --gdwarf2 --64 x_amd64/vet (dns block)
  • slow.example.com
    • Triggering command: /tmp/go-build511967270/b514/launcher.test /tmp/go-build511967270/b514/launcher.test -test.testlogfile=/tmp/go-build511967270/b514/testlog.txt -test.paniconexit0 -test.timeout=10m0s /tmp/go-build511967270/b211/vet.cfg 6718451/b186/_pkg_.a ache/go/1.25.8/x64/src/vendor/golang.org/x/text/-Wl,--no-gc-sections x_amd64/vet . --gdwarf2 --64 x_amd64/vet (dns block)
  • this-host-does-not-exist-12345.com
    • Triggering command: /tmp/go-build511967270/b523/mcp.test /tmp/go-build511967270/b523/mcp.test -test.testlogfile=/tmp/go-build511967270/b523/testlog.txt -test.paniconexit0 -test.timeout=10m0s -plu�� g_.a -plugin-opt=/usrgithub.qkg1.top/github/gh-aw-mcpg/internal/launcher x_amd64/vet -plugin-opt=-pasbash rs/otlp/otlptrac/usr/bin/runc -plugin-opt=-pas--version x_amd64/vet -uns�� .cfg elemetry.io/otel-nolocalimports x_amd64/vet -m elf_x86_64 --hash-style=gnu--version x_amd64/vet (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Copilot AI linked an issue Apr 9, 2026 that may be closed by this pull request
5 tasks
- Fix generateRandomID fallback collision risk by adding UnixNano
- Tighten payload file permissions from 0644 to 0600
- Rename walk(f) to walk_schema to avoid shadowing gojq built-in
- Upgrade gojq v0.12.18 → v0.12.19
- Add single-output contract test for walk_schema filter
- Update comments, logs, and README to reflect changes

Agent-Logs-Url: https://github.com/github/gh-aw-mcpg/sessions/b442d995-9a62-46f3-a6df-e5182255ef31

Co-authored-by: lpcox <15877973+lpcox@users.noreply.github.com>
Copilot AI changed the title [WIP] Review gojq module and update to v0.12.19 fix: gojq module review — permissions, collision, rename, upgrade Apr 9, 2026
Copilot AI requested a review from lpcox April 9, 2026 17:16
Copilot finished work on behalf of lpcox April 9, 2026 17:16
@lpcox lpcox marked this pull request as ready for review April 9, 2026 17:17
Copilot AI review requested due to automatic review settings April 9, 2026 17:17
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Addresses findings from the gojq module review by tightening payload file permissions, reducing ID collision risk in a fallback path, avoiding naming collision with gojq’s built-in walk/1, and upgrading gojq.

Changes:

  • Restrict saved payload file permissions from 0644 to 0600.
  • Rename custom jq function walkwalk_schema (and update docs/comments) to avoid shadowing built-in walk/1.
  • Upgrade dependencies github.com/itchyny/gojq to v0.12.19 (and timefmt-go to v0.1.8), and add a test documenting the “single jq output” iterator contract.
Show a summary per file
File Description
internal/middleware/README.md Updates jq filter documentation to use walk_schema and explains why.
internal/middleware/jqschema.go Updates jq filter definition/name, hardens ID fallback, tightens payload file perms, bumps version references.
internal/middleware/jqschema_test.go Adds a “single output” contract test and updates permissions expectation to 0600.
go.mod Bumps gojq to v0.12.19 and timefmt-go indirect to v0.1.8.
go.sum Updates module checksums for the upgraded dependencies.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 4/5 changed files
  • Comments generated: 4

}

logger.LogInfo("payload", "Successfully saved large payload to filesystem: path=%s, size=%d bytes, permissions=0644",
logger.LogInfo("payload", "Successfully saved large payload to filesystem: path=%s, size=%d bytes, permissions=0600",
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

os.WriteFile only applies the provided file mode when the file is created; if payload.json already exists (e.g., from a prior run or an ID collision), its existing permissions are preserved. That can leave a world-readable file even after switching to 0600. Consider explicitly enforcing the mode after writing (e.g., chmod to 0600) and/or opening with flags that ensure the file is created with the intended permissions.

Suggested change
logger.LogInfo("payload", "Successfully saved large payload to filesystem: path=%s, size=%d bytes, permissions=0600",
if err := os.Chmod(filePath, 0600); err != nil {
logger.LogError("payload", "Failed to enforce payload file permissions: path=%s, size=%d bytes, error=%v",
filePath, payloadSize, err)
return "", fmt.Errorf("failed to set payload file permissions: %w", err)
}
logger.LogInfo("payload", "Successfully saved large payload to filesystem: path=%s, size=%d bytes, enforcedPermissions=0600",

Copilot uses AI. Check for mistakes.
Comment on lines 220 to 221
logger.LogInfo("payload", "Successfully saved large payload to filesystem: path=%s, size=%d bytes, permissions=0600",
filePath, payloadSize)
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The success log hardcodes permissions=0600, but the resulting mode can still differ (e.g., if the file already existed, or if the OS applies different semantics). Consider logging the actual stat.Mode().Perm() after the write so logs match reality.

See below for a potential fix:

	// Verify file was written correctly and log the actual resulting mode
	if stat, err := os.Stat(filePath); err != nil {
		logger.LogWarn("payload", "Could not verify payload file after write: path=%s, error=%v", filePath, err)
		logger.LogInfo("payload", "Successfully saved large payload to filesystem: path=%s, size=%d bytes",
			filePath, payloadSize)
	} else {
		logger.LogInfo("payload", "Successfully saved large payload to filesystem: path=%s, size=%d bytes, permissions=%#o",
			filePath, payloadSize, stat.Mode().Perm())

Copilot uses AI. Check for mistakes.
Comment on lines +123 to +125
for _, input := range inputs {
iter := jqSchemaCode.RunWithContext(context.Background(), input)

Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test uses jqSchemaCode directly without asserting compilation succeeded first. If init-time compilation ever fails (or changes in the future), jqSchemaCode may be nil and this will panic rather than fail with a helpful assertion. Consider checking jqSchemaCompileErr/jqSchemaCode != nil up front (or calling applyJqSchema and validating the iterator behavior indirectly).

Copilot uses AI. Check for mistakes.
}

logMiddleware.Printf("Successfully compiled jq schema filter at init (gojq v0.12.18)")
logMiddleware.Printf("Successfully compiled jq schema filter at init (gojq v0.12.19)")
Copy link

Copilot AI Apr 9, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoding the gojq version in logs tends to become stale as dependencies are upgraded. Consider removing the version from this message (or sourcing it from build/module metadata) so the log stays accurate without needing manual updates.

Suggested change
logMiddleware.Printf("Successfully compiled jq schema filter at init (gojq v0.12.19)")
logMiddleware.Printf("Successfully compiled jq schema filter at init")

Copilot uses AI. Check for mistakes.
lpcox and others added 2 commits April 9, 2026 10:59
- Add os.Chmod after WriteFile to enforce 0600 on pre-existing files
- Log actual stat.Mode().Perm() instead of hardcoded permissions value
- Guard contract test with jqSchemaCompileErr/jqSchemaCode nil checks
- Remove hardcoded gojq version from init log message

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@lpcox lpcox merged commit c52441a into main Apr 9, 2026
14 checks passed
@lpcox lpcox deleted the copilot/go-fan-review-gojq-module branch April 9, 2026 18:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[go-fan] Go Module Review: gojq (github.com/itchyny/gojq)

3 participants