Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .node-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
24.21.0
24.22.1
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ Code v99.99.999

## Unreleased

### Security

- Update bundled Node.js to 24.22.1 to fix a remote code execution bug in the
Brotli decoder (CVE-2026-111497).
- Reject compressed request bodies (`Content-Encoding: br`, `gzip`, or
`deflate`) instead of decompressing them.

## [4.141.0](https://github.com/coder/code-server/releases/tag/v4.141.0) - 2026-10-08

Code v1.141.0
Expand Down
16 changes: 16 additions & 0 deletions patches/node-version.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
Bump the bundled Node.js version

Pull in Node.js security fixes (Brotli decoder RCE) ahead of upstream. Drop
this patch once upstream targets this version or newer.

Index: code-server/lib/vscode/remote/.npmrc
===================================================================
--- code-server.orig/lib/vscode/remote/.npmrc
+++ code-server/lib/vscode/remote/.npmrc
@@ -1,5 +1,5 @@
disturl="https://nodejs.org/dist"
-target="24.21.0"
+target="24.22.1"
ms_build_id="474716"
runtime="node"
build_from_source="true"
1 change: 1 addition & 0 deletions patches/series
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,4 @@ app-name.diff
remote-storage.diff
remote-secret-storage.diff
csp-hashes.diff
node-version.diff
6 changes: 4 additions & 2 deletions src/node/routes/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -132,8 +132,10 @@ export const register = async (
})
})

app.router.use(express.json())
app.router.use(express.urlencoded({ extended: true }))
// Reject compressed request bodies so unauthenticated requests cannot reach
// the zlib/Brotli decoders. Browsers never compress request bodies.
app.router.use(express.json({ inflate: false }))
app.router.use(express.urlencoded({ extended: true, inflate: false }))

app.router.use(
"/_static",
Expand Down
2 changes: 1 addition & 1 deletion src/node/vscodeSocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ export async function makeEditorSessionManagerServer(
): Promise<http.Server> {
const router = express()

router.use(express.json())
router.use(express.json({ inflate: false }))

router.get<{}, GetSessionResponse | string | unknown, undefined, { filePath?: string }>(
"/session",
Expand Down
11 changes: 11 additions & 0 deletions test/unit/node/routes/login.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,17 @@ describe("login", () => {
expect(htmlContent).toContain("Missing password")
})

it("should reject compressed request bodies", async () => {
for (const encoding of ["br", "gzip", "deflate"]) {
const resp = await codeServer().fetch("/login", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded", "Content-Encoding": encoding },
body: "password=test",
})
expect(resp.status).toBe(415)
}
})

it("should return HTML with 'Incorrect password' message", async () => {
const params = new URLSearchParams()
params.append("password", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa")
Expand Down