SSerguey Asael Shinder
Java coding notes: the JVM, and writing software that lasts

Serguey Asael Shinder: When a patch release breaks your code on purpose

· by Serguey Asael Shinder / Serguey Shinder

Django's security releases of 6 October contain a sentence most patch notes try to avoid: "This is a backward incompatible change."

The issue, CVE-2026-87890, was in GIS spatial lookups. They accepted raster values as raw bytes without requiring them to be wrapped in GDALRaster. Those bytes could hold a VRT document pointing at an external source, which made GDAL issue network requests as the Django process user. The fix is not a filter on what the bytes may contain. It is to stop accepting unwrapped bytes at all: callers must now say, in code, that the value is a raster.

Why not a softer fix. A filter would have kept existing code working and left a judgement call inside the framework: which raster documents are safe, which references are allowed. Every such rule is a place for the next bypass. Requiring an explicit wrapper moves the decision to the one place that knows where the bytes came from, the application, and makes it visible in review.

Serguey Asael Shinder: When a patch release breaks your code on purpose
When a patch release breaks your code on purpose — Serguey Asael Shinder

Why it is acceptable in a patch release. Semantic versioning says patch releases should not break callers. But the behaviour being removed was the vulnerability. Keeping it compatible would have meant keeping it exploitable for everyone who did not read the notes. Django also kept the narrow case that is safe: valid hexadecimal geometries are still accepted as bytes. The break is as small as the fix allows.

What to take from it, for your own APIs.

A release that breaks your build is annoying. A release that silently keeps the hole open is worse; you just do not find out until later.