GHSA-4mf4-73j6-mvrw: XSS

Published Sep 16, 2026
·
Updated

Impact Many djust built-in component template tags (djust.components.templatetags.) render a developer/user-supplied URL into an href / action attribute, HTML-escaping it with conditionalescape but never validating the URL scheme. HTML escaping prevents attribute breakout but does not neutralize a javascript: URI (which needs no escapable characters), so a URL value of javascript:alert(document.cookie) lands verbatim in <a href="javascript:alert(document.cookie)"> and executes in the victim's session on click.

Affected sinks (executing href/action contexts; not exhaustive): breadcrumb (djustcomponents.py:1535; advanced.py:1999,2022), djnav link/dropdown/brand (djustcomponents.py:5632,5779,5807,5830), citation URL (:6936), cookie-consent privacy link (:8240), error-page action (advanced.py:1728), form action (forms.py:1239). <img src> sinks are lower risk (javascript: does not execute via img src). No scheme validation exists anywhere in the component tags; a docstring at djustcomponents.py:781 even acknowledges the javascript: risk without mitigating it.

Severity Medium: XSS in the victim's authenticated session whenever an app renders one of these components with a URL sourced from user-controllable data; for href requires a click, worst case is the stored variant (URL persisted from one user, rendered to another). Conditional on developer usage, hence Medium rather than High.

Reproduced: breadcrumb(items=[{"label":"Home","url":"javascript:alert(document.cookie)"}]) emits <a ... href="javascript:alert(document.cookie)">Home</a>; JaVaScRiPt: case variant also passes; https:// URLs are preserved.

Patches Add a safeurl() helper that neutralizes non-allowlisted schemes (javascript:, vbscript:, data:) to # while preserving http/https/mailto/tel/relative/anchor URLs, and route every href/action/formaction/xlink:href sink through it (then HTML-escape). Add a regression + an auditast/system-check rule flagging un-routed URL-attribute interpolation.

Workarounds Do not pass user-controllable URLs to the affected built-in component tags; pre-validate URL schemes in application code before binding them to component arguments.

References Reproducer + finding writeup retained privately by the maintainer.

Affected Software

1 affected componentFixes available
pip/djust<1.0.7
1.0.7

Remediation

Recommended actions to resolve this vulnerability, in priority order.

  1. Upgrade

    Upgrade pip/djust to a version that resolves this vulnerability.

    Fixed in 1.0.7
  2. Configuration

    Implement a safe_url() helper and use it for every developer/user-supplied URL bound into the following sinks: href, action, formaction, and xlink:href. safe_url() must neutralize non-allowlisted schemes (javascript:, vbscript:, data:) by converting them to '#', while preserving http/https/mailto/tel/relative/anchor URLs. After safe_url(), HTML-escape the resulting value so it cannot break out of attributes.

    djust built-in component template tags (djust.components.templatetags.*) href/action/formaction/xlink:href URL handling = route through safe_url() and HTML-escape output
  3. Configuration

    Do not pass user-controllable URLs directly into affected built-in component tags. Pre-validate URL schemes in application code before binding them to the component arguments (so disallowed schemes never reach href/action/rendering).

    Application code using djust built-in component tags URL scheme validation before binding to component arguments = pre-validate allowlisted schemes
  4. Compensating control

    Add a regression test plus an audit_ast/system-check rule that flags any use of URL-attribute interpolation into href/action/formaction/xlink:href without routing through safe_url().

  5. Operational

    Re-scan and audit the listed affected sinks in your templates/components (breadcrumb at djust_components.py:1535 and _advanced.py:1999,2022; dj_nav links/dropdowns/brand at djust_components.py:5632,5779,5807,5830; citation URL at :6936; cookie-consent privacy link at :8240; error-page action at _advanced.py:1728; form action at _forms.py:1239) and ensure all URL values are passed through safe_url() before rendering.

Event History

Sep 16, 2026
Advisory Published
via GitHub·09:50 PM
Data Sourced
via GitHub·09:50 PM
DescriptionWeaknessAffected Software

Frequently Asked Questions

1

Which deployments are realistically exposed?

Deployments are exposed where djust built-in component template tags place developer- or user-supplied URL values into link href or form action attributes. The identified higher-risk contexts include breadcrumbs, dj_nav links, dropdowns and brands, citation URLs, cookie-consent privacy links, error-page actions, and form actions.

2

What must an attacker do to trigger the issue?

An attacker needs to cause a javascript: URL to be rendered in an affected href or action attribute and have a victim follow the link or submit the affected form. HTML escaping alone does not block this URI scheme.

3

How can I determine whether my application is affected?

Review uses of djust.components.templatetags and identify URL values passed into the listed link and form components, especially values influenced by users or other untrusted sources. Check the rendered HTML for href or action attributes containing unvalidated URL values, including javascript: schemes.

4

What can be done before an update is available?

Do not pass untrusted URL strings directly to affected component tags. Validate URLs before rendering and allow only required safe schemes, such as http and https; image src contexts are described as lower risk because javascript: does not execute through img src.

Contact

SecAlerts Pty Ltd.
132 Wickham Terrace
Fortitude Valley,
QLD 4006, Australia
info@secalerts.co
By using SecAlerts services, you agree to our services end-user license agreement. This website is safeguarded by reCAPTCHA and governed by the Google Privacy Policy and Terms of Service. All names, logos, and brands of products are owned by their respective owners, and any usage of these names, logos, and brands for identification purposes only does not imply endorsement. If you possess any content that requires removal, please get in touch with us.
© 2026 SecAlerts Pty Ltd.
ABN: 70 645 966 203, ACN: 645 966 203