Build Terraform from source during the IronBank image build instead of
downloading pre-built binaries from HashiCorp. This controls the Go
toolchain version, ensuring Go stdlib CVEs (1 Critical, 5 High, 3
Medium) fixed in Go 1.25.9 are addressed in the bundled Terraform
binary.
No upstream Terraform release is compiled with Go 1.25.9+; all use Go
1.25.8. Building from source with GOTOOLCHAIN=go1.25.9 (read from
go.mod) is the only path forward without waiting for an upstream
toolchain bump.
### Changes
- **hardening_manifest.yaml**: Replace pre-built Terraform 1.3.7 binary
with Terraform 1.14.5 source tarball (matches `install.go`). Update
terraform-provider-coder from 0.6.10 to 2.13.1 (matches `go.mod`). Add
`TERRAFORM_VERSION` build arg.
- **build_ironbank.sh**: Download Terraform source, compile with the
project's Go toolchain (1.25.9), package as terraform.zip. Add `go` to
dependencies. Update base image to UBI9.
- **Dockerfile**: Update base image from UBI8 8.7 to UBI9 9.6. Remove
python3-urllib3 to address CVE-2026-44431.
Refs ENT-1
> [!NOTE]
> Generated by Coder Agents
<details>
<summary>Implementation context (Coder Agents generated)</summary>
### Go toolchain analysis
| Component | Before | After |
|-----------|--------|-------|
| Terraform binary | Go 1.19.4 (v1.3.7 pre-built) | Go 1.25.9 (v1.14.5
built from source) |
| terraform-provider-coder | old (v0.6.10) | Go 1.24.6 (v2.13.1) |
| Coder binary | Go 1.25.9 | Go 1.25.9 (unchanged) |
### Related PRs
- #25219 — main
- #25250 — release/2.33
- #25259 — release/2.32
</details>
Backport of: #25286
Migrates Azure instance identity verification from
`go.mozilla.org/pkcs7` and `github.com/fullsailor/pkcs7` to
`github.com/smallstep/pkcs7`, using `VerifyWithChainAtTime` to validate
both the PKCS7 signature and the certificate chain in one call. The
previous code only verified the signer certificate against a set of
intermediates/roots but did not verify that the PKCS7 signature itself
covered the content, meaning tampered payloads could be accepted.
The `Options` struct is restructured to accept `Roots`, `Intermediates`,
and `CurrentTime` as explicit fields instead of embedding
`x509.VerifyOptions`. The test helper `NewAzureInstanceIdentity` now
builds a realistic 3-level certificate chain (Root CA -> Intermediate CA
-> Signing Cert) matching real Azure trust hierarchy. New tests
(`TestValidate_TamperedContent`,
`TestValidate_UntrustedCertWithValidSignature`) confirm tampered and
untrusted envelopes are rejected.
Addresses GHSA-6x44-w3xg-hqqf.
> [!NOTE]
> This PR was authored by Coder Agents.
<details>
<summary>Implementation Plan</summary>
| File | Summary |
|------|---------|
| `coderd/azureidentity/azureidentity.go` | Replace `signer.Verify()`
with `VerifyWithChainAtTime`; restructure `Options` struct; add
`ParseCertificates()` helper |
| `coderd/azureidentity/azureidentity_test.go` | Add `testCertChain`
builder, tampered-content and untrusted-cert tests; update existing
tests for new `Options` API |
| `coderd/coderd.go` | Change `AzureCertificates` field from
`x509.VerifyOptions` to `azureidentity.Options` |
| `coderd/workspaceresourceauth.go` | Pass `api.AzureCertificates`
directly instead of wrapping |
| `coderd/coderdtest/coderdtest.go` | Migrate to `smallstep/pkcs7`;
build 3-level cert chain in test helper |
| `go.mod` / `go.sum` | Add `github.com/smallstep/pkcs7`; remove
`fullsailor/pkcs7` and `go.mozilla.org/pkcs7` |
</details>
<!--
If you have used AI to produce some or all of this PR, please ensure you
have read our [AI Contribution
guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING)
before submitting.
-->
Co-authored-by: Jakub Domeracki <jakub@coder.com>
Bumps Go toolchain from 1.25.9 to 1.25.10 on the v2.31.x release branch
to address 11 Go stdlib CVEs identified in the IronBank v2.31.11 scan.
Go 1.25.10 ([release notes](https://go.dev/doc/devel/release#go1.25.10))
includes security fixes to the go command, the pack tool, and the
`html/template`, `net`, `net/http`, `net/http/httputil`, `net/mail`, and
`syscall` packages.
Fixes: https://linear.app/codercom/issue/ENT-2
<details>
<summary>CVEs addressed</summary>
**High**
- CVE-2026-42501: Malicious module proxy can bypass checksum database
validation
- CVE-2026-39820: net/mail ParseAddress/ParseAddressList excessive
CPU/memory
- CVE-2026-33811: net LookupCNAME double-free and crash (cgo resolver)
- CVE-2026-33814: net/http HTTP/2 SETTINGS MAX_FRAME_SIZE=0 infinite
loop
- CVE-2026-39836: net Dial/LookupPort panic on Windows with NUL byte
(Windows-only)
**Medium**
- CVE-2026-39819: go bug writes to predictable temp file names (symlink
attack)
- CVE-2026-39817: go tool pack unsanitized output filenames (arbitrary
file write)
**Low**
- CVE-2026-42499: net/mail consumePhrase DoS
- CVE-2026-39826: html/template incorrect escaping in script tags
- CVE-2026-39825: net/http/httputil ReverseProxy hidden query parameters
- CVE-2026-39823: html/template XSS via whitespace in meta content
attribute
</details>
<details>
<summary>Note on Terraform binary</summary>
The Terraform binary bundled in the IronBank image is downloaded from
HashiCorp releases. Rebuilding it with Go 1.25.10+ requires an upstream
Terraform release. This PR addresses the Coder binary; the Terraform
binary fix depends on upstream.
</details>
> 🤖 Generated with [Coder Agents](https://coder.com)
> Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
Cherry-pick of #24165 to `release/2.31`.
Removes the flaky pagination query key test that timed out in CI (6204ms
vs 5000ms limit) because `renderWithAuth` boots 12+ MSW round-trips
before the page mounts.
On this branch `WorkspacesPage.stories.tsx` does not exist, so the test
is removed rather than moved to a story.
> 🤖 Generated by Coder Agent
Bump `github.com/yuin/goldmark` from v1.7.16 to v1.7.17 to fix
[CVE-2026-5160](https://nvd.nist.gov/vuln/detail/CVE-2026-5160).
goldmark v1.7.16 is vulnerable to XSS due to improper ordering of URL
validation and normalization. The renderer validates link destinations
using a prefix-based check (`IsDangerousURL`) before resolving HTML
entities, allowing an attacker to bypass validation with entity-encoded
`javascript:` URIs.
This is the minimal fix for the IronBank finding on the
`coder/coder-enterprise/coder-service-2:2.31.11` image. The fix is
already on `main` (v1.8.2 via Hugo bump in #23957); this targets the
v2.31.x release branch with only the goldmark dependency change.
Closes [ENT-8](https://linear.app/codercom/issue/ENT-8)
> Generated by Coder Agents
Bumps `github.com/go-git/go-git/v5` from 5.18.0 to 5.19.0 on the
release/2.31 branch to fix CVE-2026-45022 (GHSA-389r-gv7p-r3rp):
go-git's improper parsing of specially crafted objects may lead to
inconsistent interpretation compared to upstream Git.
Equivalent of [#25124](https://github.com/coder/coder/pull/25124) on
main, adapted for the release/2.31 dependency tree.
Supersedes #25215 (rebased on top of #25212, #25213, #25214).
Fixes https://linear.app/codercom/issue/ENT-3
> [!NOTE]
> 🤖 Generated with [Coder Agents](https://coder.com)
Cherry-picks the gomarkdown/markdown bump from main (#24567) to
`release/2.31`.
Updates `github.com/gomarkdown/markdown` from
`v0.0.0-20240930133441-72d49d9543d8` to
`v0.0.0-20260411013819-759bbc3e3207`, fixing GHSA-77fj-vx54-gvh7 (OOB
Read in SmartypantsRenderer).
Note: `coderd/render/markdown.go` uses `html.CommonFlags` which enables
Smartypants by default, so this code path is reachable. The bump
resolves the IronBank finding for image
`coder/coder-enterprise/coder-service-2:2.31.11`.
<details><summary>Codebase verification</summary>
Only `coderd/render/markdown.go` imports `gomarkdown`. It calls
`html.NewRenderer` with `html.CommonFlags`, which includes the
Smartypants flag. No explicit SmartypantsRenderer configuration exists,
but the default flags enable smartypants processing. The patched
revision fixes the OOB read in that code path.
</details>
Closes https://linear.app/codercom/issue/ENT-6
> 🤖 Generated with [Coder Agents](https://coder.com)
Co-authored-by: Lukasz <CommanderK5@users.noreply.github.com>
Bumps `golang.org/x/net` from v0.52.0 to v0.53.0 on the v2.31.x release
branch to fix CVE-2026-33814, an HTTP/2 infinite loop DoS in
`x/net/http2` triggered by a `SETTINGS_MAX_FRAME_SIZE` of 0.
Refs [ENT-10](https://linear.app/codercom/issue/ENT-10)
Cherry-pick of the relevant portion of #24259.
### Changes
- `golang.org/x/net` v0.52.0 -> v0.53.0
- Transitive bumps: `x/crypto` v0.50.0, `x/sys` v0.43.0, `x/term`
v0.42.0, `x/text` v0.36.0
<details><summary>Context</summary>
The original PR #24259 (commit `10f0786`) bumps 7 `golang.org/x`
packages. A direct cherry-pick conflicts due to divergent `x/mod`
versions between `main` and `release/2.31`. This PR performs the minimal
manual bump of `go get golang.org/x/net@v0.53.0` followed by `go mod
tidy`.
</details>
> 🤖 Generated with [Coder Agents](https://coder.com)
>
> Co-Authored-By: Claude Sonnet 4 <noreply@anthropic.com>
Bumps `github.com/aws/aws-sdk-go-v2/service/s3` from v1.97.1 to v1.97.3
on the v2.31.x release branch to fix the EventStream header decoder DoS
vulnerability
([GHSA-xmrv-pmrh-hhx2](https://github.com/aws/aws-sdk-go-v2/security/advisories/GHSA-xmrv-pmrh-hhx2),
CVSS 5.9).
Cherry-pick equivalent of d87c5ef4 from main
([#24136](https://github.com/coder/coder/pull/24136)).
Fixes ENT-7
<details><summary>Context</summary>
IronBank image `coder/coder-enterprise/coder-service-2:2.31.11` flagged
by VAT scanner for this vulnerability. The fix was already on `main`;
this brings it to the release branch.
</details>
> 🤖 Generated with [Coder Agents](https://coder.com)
Cherry-pick backport of #24474 and #24529 to `release/2.31`.
- #24474: fix(coderd): add frame-ancestors CSP directive to prevent
clickjacking
- #24529: fix(coderd): omit frame-ancestors CSP for embed routes
Both commits cherry-picked cleanly with no conflicts.
> Generated by Coder Agents
Backport of https://github.com/coder/coder/pull/24332 to `release/2.31`.
Moves the `UpdateExternalAuthLink` call to immediately after
`TokenSource.Token()` succeeds (before validation). GitHub rotates
refresh tokens on use, so if post-refresh validation fails (e.g.
rate-limited 403), the new token was previously silently discarded,
forcing manual re-authentication.
Original PR: #24332
Merge commit: 2a1984f0e8
**Note:** This branch includes the cherry-pick of #22904 (optimistic
locking) as a prerequisite since #24332's tests depend on it. The #22904
backport PR is #24902. Once that merges, the overlapping commit in this
PR will be a no-op.
Cherry-picks applied cleanly with no conflicts.
> Generated by Coder Agents
---------
Co-authored-by: Kyle Carberry <kyle@coder.com>
Co-authored-by: Mathias Fredriksson <mafredri@gmail.com>
Backport of https://github.com/coder/coder/pull/22904 to `release/2.31`.
Adds an optimistic lock to `UpdateExternalAuthLinkRefreshToken` so that
a concurrent caller that lost a token-refresh race cannot overwrite a
valid token stored by the winner. The SQL `WHERE` clause now includes
`AND oauth_refresh_token = @old_oauth_refresh_token`.
Original PR: #22904
Merge commit: 53e52aef78
Cherry-pick applied cleanly with no conflicts.
> Generated by Coder Agents
Co-authored-by: Kyle Carberry <kyle@coder.com>
Cherry-pick of #24650 and #24765 to release/2.31.
Adds a confirmation dialog before executing commands from the
`?command=` URL parameter in the terminal page. Canceling closes the
terminal window.
> 🤖 Generated by Coder Agents
---------
Co-authored-by: Seth Shelnutt <seth@coder.com>
## Summary
- backport `golang.org/x/net` 0.52.0, `go-getter` 1.8.6, and
`EventStream` 1.7.8 to `release/2.31`
- backport the Go toolchain bump to 1.25.9
- include the latest local backport commits on
`sec/release-2.31-security`
## Testing
- not run
---------
Co-authored-by: Ethan <39577870+ethanndickson@users.noreply.github.com>
Backport of #23835.
Audit and connection log pages were timing out due to expensive COUNT(*)
queries over large tables. This commit adds opt-in count capping:
requests can return a `count_cap` field signaling that the count was
truncated at a threshold, avoiding full table scans that caused page
timeouts.
Text-cast UUID comparisons in regosql-generated authorization queries
also contributed to the slowdown by preventing index usage for
connection and audit log queries. These now emit native UUID operators.
Frontend changes handle the capped state in usePaginatedQuery and
PaginationWidget, optionally displaying a capped count in the pagination
UI (e.g. "Showing 2,076 to 2,100 of 2,000+ logs")
---
Cherry picked from 86ca61d6ca
## Summary
- backport the high/critical Iron Bank dependency fixes needed on
release/2.31
- bump github.com/go-jose/go-jose/v4 to v4.1.4
- bump google.golang.org/grpc to v1.79.3 and github.com/buger/jsonparser
to v1.1.2
## Context
- main already contains the required fixes, so no main patch PR was
needed
- I checked whether the existing main patches could be cherry-picked
directly
- grpc and jsonparser have matching commits on main, but the backport
branch has drift in the same dependency blocks, so the release-branch
patch was applied as the minimal equivalent dependency bump instead of a
clean cherry-pick
## Validation
- make lint is blocked locally because the installed golangci-lint
binary was built with Go 1.24 while this branch targets Go 1.25.8
- go test ./... progresses and then fails in Docker-backed tests because
/var/run/docker.sock is unavailable in this environment
## What
Bumps `coder/tailscale` to
[`e956a95`](https://github.com/coder/tailscale/commit/e956a950740bd737c55451f56e77038f7430a919)
([PR #113](https://github.com/coder/tailscale/pull/113)) to pick up the
`RTM_MISS` fix for the Darwin network monitor.
## Why
On Darwin, `RTM_MISS` route-socket messages (fired on every failed route
lookup) were not filtered by `netmon`, causing each one to be treated as
a `LinkChange`. When netcheck sends STUN probes to an IPv6 address with
no route, this creates a self-sustaining feedback loop: `RTM_MISS` →
`LinkChange` → `ReSTUN` → netcheck → v6 STUN probe → `RTM_MISS` → …
The loop drives DERP home-region flapping at ~70× baseline, which at
fleet scale saturates PostgreSQL's `NOTIFY` lock and causes coordinator
health-check timeouts.
The upstream fix adds a single `if msg.Type == unix.RTM_MISS { return
true }` check to `skipRouteMessage`. This is safe because `RTM_MISS` is
a lookup-path signal, not a table-mutation signal — route withdrawals
always emit `RTM_DELETE` before any subsequent lookup can miss.
## Scope
This is a targeted workaround to unblock a customer. The root cause —
why certain macOS versions generate elevated `RTM_MISS` traffic (likely
a change in IPv6 route-table initialization) — requires further
investigation.
Backport of #23367 to release/2.31.
The trivy v0.41.0 release assets have been removed from GitHub, causing
the dogfood image build to fail with `gzip: stdin: not in gzip format` —
the 404 HTML response gets piped into `tar`.
This is blocking #23941.
> 🤖 This PR was created with the help of Coder Agents, and needs a human
review. 🧑💻
Backport of #23090 to `release/2.31`.
When a user creates a workspace, opens the web terminal, then the
workspace stops but the web terminal remains open, the web terminal will
retry the connection. Coder would issue a HTTP 502 Bad Gateway response
when this occurred because coderd could not connect to the workspace
agent, however this is problematic as any load balancer sitting in front
of Coder sees a 502 and thinks Coder is unhealthy.
This PR changes the response to a HTTP 404 after internal discussion.
Cherry-picked from merge commit
c33812a430.
Bumps aibridge to v1.0.9, which forwards the `Anthropic-Beta` header
from client requests to the upstream Anthropic API:
https://github.com/coder/aibridge/pull/205
This fixes the `context_management: Extra inputs are not permitted`
error when using Claude Code with AI Bridge.
Note: v1.0.8 was retracted due to a conflict marker cached by the Go
module proxy https://github.com/coder/aibridge/pull/208. v1.0.9 contains
the same fix.
Switch from workspace stop/start operations to the dedicated tasks pause
and resume endpoints for cleaner semantics.
(cherry picked from commit bf639d0016)
<!--
If you have used AI to produce some or all of this PR, please ensure you
have read our [AI Contribution
guidelines](https://coder.com/docs/about/contributing/AI_CONTRIBUTING)
before submitting.
-->
The pause/resume endpoints were only registered under /api/experimental
but the frontend and Go SDK were calling /api/v2, resulting in 404s.
Register the routes in the v2 group, update the SDK client paths, and
fix swagger annotations (Accept → Produce) since these POST endpoints
have no request body.
(cherry picked from commit 9d2aed88c4)
Cherry-pick of #22461 to `release/2.31`.
Applies the non-browser websocket auth principle from #22226 to
remaining
`codersdk` websocket callsites, replacing cookie-jar session auth with
header-token auth. Fixes `401` failures on deployments with
`--host-prefix-cookie` enabled.
Closes#22461 (cherry-pick)
---------
Co-authored-by: ethan <ethanndickson@gmail.com>
Fixes https://github.com/coder/coder/issues/22375
Updates `stringutil.Truncate` to properly handle multi-byte UTF-8
characters.
Adds tests for multi-byte truncation with word boundary.
Created by Mux using Opus 4.6
(cherry picked from commit 0cfa03718e)