Brotli's decoder flaw
One crafted Brotli stream can take over a server, or the client that fetched it
On Saturday's Hacker News front page, the story to act on is a flaw in Brotli, Google's compression library, which sits inside most software that speaks HTTP. A crafted Brotli stream overflows a buffer in the decoder, and it works in both directions. A malicious client can take over an unpatched server, and a malicious server can take over a client that accepts compressed responses. Every version from 1.0.3 to 1.2.0 is affected. The fix went into Brotli's source in February, but it stayed unreleased until the flaw was disclosed in October, so every project that bundles its own copy has to ship its own update.
Python apps without a Brotli import
A Python app can be exposed without ever importing Brotli
requests → urllib3 → Brotli ≤ 1.2.0 # if installed httpx[brotli] → Brotli ≤ 1.2.0 aiohttp → Brotli ≤ 1.2.0 $ pip show Brotli brotlicffi
Python is the easy one to miss. Requests, httpx and aiohttp decode Brotli automatically whenever the package is installed, so an app can be reached through a webhook delivery, a link preview or a crawler, with no Brotli import anywhere in its own code. As of October 23, the advisory databases had yet to map the flaw to either Python package, so pip-audit and Dependabot stay quiet, and the check is by hand. Commenter anttihaapala went through every Python deployment and found zero with it installed, because those clients treat Brotli as optional.
Fixed releases
Patch the runtime, then rebuild every image that bundles it
br request bodies at the proxy, and turn off Brotli decoding on outbound callsNode, Bun, Envoy and the Python packages all have fixed releases, and curl needs its Brotli dependency updated. A container image built on an old copy stays vulnerable until it is rebuilt. Until then, reject Brotli request bodies at the proxy. Removing Brotli from the accept header leaves outbound calls exposed, because a malicious server can send a Brotli response anyway, so turn the decoder off for those. Apache and nginx leave Brotli decoding off by default.
Roc against C
Roc compresses at nearly C speed with every bounds check still on
That Brotli bug is an unchecked memory write, and Roc code can't make one. Roc is a functional language with no way to skip a bounds check, and Richard Feldman tuned roc-deflate, a compression package written in it, to race libdeflate, the hand-tuned C library. In the median case Roc runs less than a tenth slower, and on some files it is faster. When a commenter asked whether the compression itself was as good, the author, rtfeldman, replied that the output is identical. Roc is still weeks from its first numbered release, and C keeps the higher ceiling.
uv check
uv check installs your dependencies and type-checks the project with ty
$ uv check # whole project $ uv check --all-packages # every workspace package $ uv check --script example.py # a script's own deps
For Python projects, Astral has wired its type checker, ty, into uv. One command prepares the environment, installs the dependencies and type-checks the code, with the ty version pinned in the lockfile, so CI and every laptop run the same checker. Single-file scripts that declare their dependencies inline now get completions and go-to-definition in the editor too. Commenter xavdid called bad editor support the biggest complaint about those scripts. It is experimental, and the editor setup is opt-in, because installing dependencies can run third-party code.
Twelve years of rqlite
rqlite has replicated SQLite through a Raft log since 2014
Philip O'Toole looked back on twelve years of rqlite, which puts every SQLite write through a Raft log so that losing a node doesn't lose the data. About a dozen projects followed it, and they split three ways. Consensus keeps a cluster, streaming copies one machine's log to S3, and merging lets many writers diverge. The money went to the hosted versions, and Supabase bought Turso this year. Commenter gregsadetsky points out that rqlite officially leaves explicit begin and commit unsupported, and runs a bulk request as all or nothing instead. If a restore from S3 is fast enough, I'd run Litestream, and if the app can't wait for one, rqlite.

















