Skip to content

Bump golang.org/x/text to v0.39.0 to fix GO-2026-5970 - #832

Merged
FelixPhipps merged 1 commit into
masterfrom
bump-x-text-v0.39.0
Sep 8, 2026
Merged

Bump golang.org/x/text to v0.39.0 to fix GO-2026-5970#832
FelixPhipps merged 1 commit into
masterfrom
bump-x-text-v0.39.0

Conversation

@wallrj-cyberark

Copy link
Copy Markdown
Contributor

Why now?

govulncheck has failed on master every night since at least 4 September, and it blocks the v1.12.0-alpha.0 pre-release we want to cut for end-to-end testing. make verify-govulncheck reported 8 vulnerabilities that our code actually calls.

This PR fixes the one that is a module dependency rather than a standard library issue:

GO-2026-5970 — infinite loop on invalid input in golang.org/x/text, fixed in v0.39.0.

We genuinely reach it. servicediscovery.Client.DiscoverServices calls http.Client.Do, which reaches norm.Form.Bytes, norm.Form.IsNormalString, norm.Form.QuickSpan and norm.Form.String.

The other seven findings are all in the standard library and need a Go toolchain upgrade, which is #831. The two PRs are independent and can merge in either order; together they take govulncheck to zero.

What changed

go get golang.org/x/text@v0.39.0 && go mod tidy, then make generate.

Only go.mod and go.sum. x/text v0.39.0 requires golang.org/x/sync v0.21.0, so that moves from v0.20.0 too. make generate produced no further changes — in particular LICENSES is untouched, since both modules were already listed under the same licence.

Both are indirect dependencies, so there is no source change to review.

Testing

govulncheck drops from 8 called vulnerabilities to exactly the 7 standard library ones, and 436 unit tests pass

make verify-govulncheck before this change reported 8. After it, the x/text finding is gone and only the standard library findings remain, each waiting on #831:

Vulnerability #1: GO-2026-6218  net/url@go1.26.4        -> fixed in go1.26.6
Vulnerability #2: GO-2026-6091  html/template@go1.26.4  -> fixed in go1.26.6
Vulnerability #3: GO-2026-6090  crypto/tls@go1.26.4     -> fixed in go1.26.6
Vulnerability #4: GO-2026-6089  net/http@go1.26.4       -> fixed in go1.26.6
Vulnerability #5: GO-2026-5972  encoding/asn1@go1.26.4  -> fixed in go1.26.6
Vulnerability #6: GO-2026-5856  crypto/tls@go1.26.4     -> fixed in go1.26.5
Vulnerability #7: GO-2026-5026  net/http@go1.26.4       -> fixed in go1.26.6

Your code is affected by 7 vulnerabilities from the Go standard library.

make test-unit:

DONE 436 tests, 4 skipped in 96.517s

govulncheck has failed on master every night since at least 4 September.
GO-2026-5970 is an infinite loop on invalid input in golang.org/x/text,
and our code reaches it: servicediscovery.Client.DiscoverServices calls
http.Client.Do, which reaches norm.Form.

x/text v0.39.0 requires golang.org/x/sync v0.21.0, so that moves too.

This clears the only module-level finding. The other seven are all in
the standard library and are cleared by the Go toolchain upgrade in the
companion pull request.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Richard Wall <richard.wall@cyberark.com>

@FelixPhipps FelixPhipps left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Verdict: approve — merge it. Two-line dependency bump, forced by MVS, no source change, CI green.

I pulled golang.org/x/text@v0.39.0's own go.mod to check the knock-on versions:

module golang.org/x/text
go 1.25.0
require golang.org/x/tools v0.47.0 // tagx:ignore
require (
	golang.org/x/mod v0.37.0 // indirect; tagx:ignore
	golang.org/x/sync v0.21.0 // indirect
)

That accounts for every line in the diff, and confirms there was no smaller version of this change available.

Two corrections to the description

Neither changes the outcome, but both would mislead the next person reading it.

  1. "Both are indirect dependencies" — x/sync is direct. go.mod:19 has no // indirect marker, and we import it at pkg/agent/run.go:22 for errgroup. The conclusion still holds (v0.20.0 → v0.21.0 is a minor bump, nothing in errgroup changed), but the reasoning as written invites skipping that check, and next time the same sentence might cover a bump that does warrant a look.

  2. x/sync isn't the only knock-on. go.sum also moves x/mod v0.36.0 → v0.37.0 and x/tools v0.45.0 → v0.47.0. They're go.sum-only because we build no packages from them, so nothing is wrong — but the description reads as though x/sync were the sole side effect, and a reviewer checking the diff against the prose will trip over the two extra pairs.

One point in the description's favour, worth making explicit

x/text v0.39.0 declares go 1.25.0, which is below this module's go 1.26.4 directive. So it raises no toolchain floor and the "independent, merge in either order" claim with respect to #831 genuinely holds — worth stating, since a dependency that demanded a newer go directive is exactly what would have broken that independence.

On the LICENSES check

True, but weaker evidence than it looks: LICENSES records module path and licence with no version at all (golang.org/x/text,BSD-3-Clause, line 120), so it could not have changed for a version bump regardless. Not a problem — just don't read it as confirmation that nothing else moved.

Reachability, in context

The trace is real, and I'd frame the exposure slightly more precisely than the description does. The path govulncheck reports — DiscoverServiceshttp.Client.Donorm.Form.*, via x/net/idna — normalises the URL the agent constructs itself from the configured subdomain, so the input on that specific path isn't attacker-controlled.

The same norm.Form code is reached with response-derived hosts by the identity, discoverycontext and secrets_manager clients, and those were exactly the hosts constrained by 13fb885 last week. The allowlist runs before the request is issued, so a rejected host never reaches norm.Form at all.

Net: a genuinely called vulnerability with narrow practical exposure, already partially fenced. Merge it on govulncheck-hygiene grounds — it's the right call, and it unblocks v1.12.0-alpha.0 — just not something to treat as urgent in its own right.

E2E labels

Unlike #831, I would not ask for the test-e2e / test-ark / test-ngts labels here. No source change, no tooling change, no chart change — the skipped jobs cost nothing on this one.

🤖 Generated with Claude Code

@FelixPhipps
FelixPhipps merged commit bb65748 into master Sep 8, 2026
5 checks passed
wallrj-cyberark added a commit that referenced this pull request Sep 8, 2026
Ran `make upgrade-klone` followed by `make generate`.

The motivation is govulncheck, which has failed on master every night
since at least 4 September. Go 1.27.1 clears seven of the eight
vulnerabilities our code calls, all of them in the standard library:
GO-2026-6218, GO-2026-6091, GO-2026-6090, GO-2026-6089, GO-2026-5972,
GO-2026-5856 and GO-2026-5026. The remaining one is in golang.org/x/text
and is handled separately in #832.

Three changes were needed to keep the build green:

- Go 1.27 re-implemented encoding/json on top of encoding/json/v2, so a
  failing MarshalJSON on a json.RawMessage now names *jsontext.Value
  rather than json.RawMessage. One test asserted that whole message, so
  it now asserts the fragments that are not a standard library type name.
- The upgrade enables the nolintlint linter, which rejects a space
  between the comment marker and the directive. Three existing
  directives needed the space removing.
- Upstream replaced the make-self-upgrade workflow with a Renovate
  JSONata manager, so `make generate` deletes it. Our
  .github/renovate.json5 already extends the makefile-modules config
  that carries the replacement.

Verified with verify, test and all three label-gated e2e suites
(test-e2e, ark-test-e2e, ngts-test-e2e), all passing.

Co-Authored-By: Claude <noreply@anthropic.com>
Signed-off-by: Richard Wall <richard.wall@cyberark.com>
@wallrj-cyberark

Copy link
Copy Markdown
Contributor Author

Thanks for merging, and both corrections are right. Recording them here since the description is now the historical record and I would rather it not mislead anyone reading back.

x/sync is a direct dependency, not indirect. I checked after your comment: go.mod:19 carries no // indirect marker, and we import it at pkg/agent/run.go:22 for errgroup. My "both are indirect dependencies, so there is no source change to review" was simply wrong, and wrong in the way that matters — it presents a conclusion as though no check were needed. The conclusion happened to hold here, because nothing in errgroup changed between v0.20.0 and v0.21.0, but the reasoning would have waved through a bump where it did not.

The knock-on set is wider than I said. go.sum also moves x/mod v0.36.0 to v0.37.0 and x/tools v0.45.0 to v0.47.0. Confirmed in the diff. They are go.sum-only because we build no packages from them, but describing x/sync as the sole side effect does not match what a reviewer sees in the diff.

Your point about x/text v0.39.0 declaring go 1.25.0 is a better argument for independence from #831 than anything I wrote. A dependency that raised the toolchain floor is exactly what would have broken the "merge in either order" claim, and I asserted that independence without checking the one thing that could have falsified it.

Taking the LICENSES point too. It records module path and licence with no version, so it could not have changed for a version bump either way. It was weaker evidence than I presented it as.

On exposure, your framing is more precise than mine and worth keeping: the reported trace normalises a URL the agent constructs itself from configured input, while the response-derived hosts that reach the same code are the ones fenced by 13fb885 last week, with the allowlist running before the request is issued.

For the record, #831 is now merged too, so master should be at zero called vulnerabilities. I am verifying that now and will follow up if it is not.

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.

2 participants