A librsvg use-after-free, with RCE confirmed across multiple applications.
01 / the bug
Same name, different entity.
librsvg uses libxml2 to read the XML inside an SVG image. While expanding an entity, an XInclude can start parsing another document. Both parses share librsvg’s entity map.
If the included document declares an entity with the same name, librsvg replaces the entry and frees the old one. The outer parse still holds a pointer to it. When it resumes, it uses freed memory that may now belong to another object.
01 / retainouter parse↓xmlEntity Apointer still held
02 / replacenested XInclude↓free(A)same entity name
I confirmed RCE in several applications using librsvg. Next.js and Ghost are the cases I reported that led to public advisories, covered below.
Each product carried input into the parser differently. Having librsvg among the dependencies does not, by itself, make an application exploitable.
01
Next.js / ImageResponse
text → Satori → SVG → Sharp / libvips → librsvg
A separate escaping bug in Satori let attacker-controlled text alter the generated SVG. In the Node.js runtime, ImageResponse passed that SVG into the native image pipeline. This path does not apply to the Edge runtime.
When the API accepted an attacker-controlled image source, a crafted image could pass its SVG rejection and later be decoded as SVG by Sharp/libvips. This exposed the UAF to unauthenticated requests on glibc-based Linux, without involving Satori.
A staff user, including a Contributor, could create a bookmark card for a site they controlled. Processing the card image reached the vulnerable library. This path also allowed command execution on the server.