security: fix audit findings — C1, H1–H4, M1–M5#998
Open
lhotea wants to merge 6 commits into
Open
Conversation
added 6 commits
May 22, 2026 18:14
…, H2) Previously, internal/config/generator.go renamed the existing config to <path>.bkp and recreated the file with default 0666 mode. The .bkp file was never cleaned up and inherited the permissive mode, so token rotation didn't actually retire the old token from disk and any local account could read it. Now: atomic write via tempfile + os.Rename, mode 0o600 explicitly. No .bkp is left behind. Adds a startup permission check that warns on non-Windows hosts when the config file is group/world-readable. Adds tests asserting mode and absence of .bkp.
Issue summary, description, comment body, and user displayName fields are returned by the Jira server as untrusted UTF-8 and were previously rendered without filtering. A malicious account could embed OSC 8 hyperlinks (CWE-150), OSC 52 clipboard writes, or DECSET 1049 to corrupt the user's terminal when 'jira issue view' was run. Adds internal/view/sanitize.go with SanitizeTerminal, which strips C0/C1 controls and any non-SGR escape sequence. All call sites that emit server-controlled strings now route through it. Tests cover OSC 8, OSC 52, DECSET 1049, plain SGR pass-through, and UTF-8 preservation.
httputil.DumpRequest was called with body=true after SetBasicAuth / Authorization header was set, which leaked Bearer/Basic credentials to stdout when --debug was used. Clone the request and replace Authorization, Cookie, and Proxy-Authorization with REDACTED before dumping. The original request keeps its real headers so downstream http.Client.Do still authenticates. prettyPrintDump now writes through an io.Writer so its output can be captured in tests. Adds regression tests asserting the dump contains REDACTED and not the real Bearer token / Basic credentials, while the original request is preserved.
Bumps golang.org/x/net from v0.38.0 to v0.55.0 to pull in fixes for known vulnerabilities reported by govulncheck (GO-2025-3503, GO-2025-3595, GO-2025-3942, GO-2026-4441, GO-2026-4918, CVE-2025-47911, CVE-2025-22872, CVE-2025-22870, CVE-2024-45338). A govulncheck/gosec CI workflow was prepared but is omitted from this PR because the OAuth token used to push lacks the 'workflow' scope. Adding that workflow can be a maintainer follow-up.
…edact paths (H3, M4) - Refuse to use the mTLS client key when its file mode is group- or world-readable on POSIX. Skipped on Windows (mode bits don't reflect ACLs there). - Remove transport.TLSClientConfig.Renegotiation = RenegotiateFreelyAsClient. Default RenegotiateNever is correct; Jira does not need renegotiation. - Stop logging the user-supplied CA path / cert path in log.Fatalf output. The wrapped Go errors are still informative without the path concatenation. Type-checked via go build/vet; mTLS behaviour is covered by integration smoke testing rather than unit tests (no certs available in CI).
M2: --insecure now warns loudly at config write time and requires an explicit interactive confirmation before persisting insecure: true to the YAML. Every subsequent command load also prints a one-line stderr banner so the user is reminded that TLS verification is off. M3: JIRA_API_TOKEN env var now takes precedence over the api_token key in the YAML config. This makes credential rotation immediate instead of requiring a config edit, and removes the operational foot-gun of a stale on-disk token shadowing a freshly exported one. README updated to document the new resolution order. M5: bump glamour 0.9.1 -> 1.0.0 so the transitive goldmark dependency moves from 1.7.8 to 1.7.13, picking up the CVE-2026-5160 fix (DoS via crafted markdown link reference definitions).
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
Fixes 10 findings from an internal v1.7.0 security audit: 1 Critical, 4 High, 5 Medium. No functional regressions; all existing tests pass on this branch identically to
mainon the development host (two pre-existing Windows-only failures inTestGetIssueRaw/TestGetPagerare unchanged — not caused by this branch).Findings addressed
Authorization,Cookie,Proxy-Authorizationfrom--debugHTTP dumps viareq.Clone+REDACTED. Original request retains real headers soDo()still works.os.Rename) with mode0600..bkpresidue containing prior credentials onjira initrerun.runtime.GOOS != "windows"because Unix mode bits don't reflect Windows ACLs).golang.org/x/netv0.38.0 → v0.55.0 to cleargovulncheckfindings (CVE-2025-22872, CVE-2025-22870, CVE-2024-45338, GO-2025-3503/3595/3942, GO-2026-4441/4918, CVE-2025-47911).mfinal byte preserved so colour output still works.insecure: true— confirmation prompt atjira init, stderr banner on every invocation.api/client.go(consultJIRA_API_TOKENbefore viper-loadedapi_token). README updated.tls.RenegotiateFreelyAsClient, default toRenegotiateNever. Redact CA/cert filesystem paths fromlog.Fatalfmessages so they don't leak the user's home layout in stderr.glamour0.9.1 → 1.0.0 (pullsgoldmark1.7.13).Verification
go build ./...— clean.go vet ./...— clean.go test ./...— same pass/fail set asorigin/mainon the Windows host (TestGetIssueRaw/TestGetPagerwere already failing onmain; reproduce by checking outmainand running the same command).govulncheck ./...—No vulnerabilities found.(was 7 imported + 2 module onmain).BEARER-TEST-LEAKAGE-CANARY-XYZdoes not appear in--debugoutput (onlyAuthorization: REDACTED); insecure stderr banner fires wheninsecure: true.Out of scope / follow-ups for maintainers
internal/cmd/root/root.go:checkForJiraTokenonly consults env / netrc / keyring — not viper-loaded YAMLapi_token. The M3 precedence fix inapi/client.gomatches the audit ask; the root.go gate quirk is documented here for a follow-up rather than altered in this PR.govulncheck+gosecCI workflow (.github/workflows/security.yml) was prepared but is omitted from this PR because the OAuth token used to push lacks theworkflowscope. Adding it can be a maintainer follow-up — the dependency bump in this PR already clears the current findings.🤖 Generated with Claude Code