Executive brief
djust is a Django template engine that processes HTML markup. Six independent defects in its auto-escaping mechanism allow attackers to inject arbitrary JavaScript code into web pages by exploiting filters, context variables, and custom tags that fail to properly escape user input. An attacker can achieve stored or reflected cross-site scripting (XSS) to steal sessions, deface pages, or steal sensitive data from users viewing the affected application.
Technical details
djust implements template auto-escaping to prevent XSS, but six independent vulnerabilities bypass this protection. Defects include: (1) the `linenumbers` filter defers escaping to render time, allowing `|safe` to suppress it; (2) the `escape` filter is a no-op that returns input unchanged, making chains like `|escape|safe` equivalent to bare `|safe`; (3) `unordered_list` and `safeseq` emit strings unescaped under a safety grant meant for escaped sequences; (4) safety grants persist across view renderings, causing context variables marked safe once to remain safe indefinitely (including across WebSocket events); (5) custom tag handlers including djust's own `render_slot` return output raw without Django's conditional escaping; and (6) `linebreaks` and `linebreaksbr` emit HTML tags without escaping content, forcing developers to use `|safe` to render correctly, which then emits user content live. Defects 3–5 require no unusual filter chains or developer action (component slots and context reuse are standard patterns). All require network access to an affected application rendering untrusted input. Patches are available in versions 1.1.1 and 1.2.0.
Affected products
- djust djust 1.1.0 and earlier
Timeline
- 2026-09-17: disclosed: GHSA-9395-2g46-rj3f advisory published
- 2026-09-17: patched: Fixed in djust 1.1.1 and 1.2.0