IBM Sterling Connect Direct for Unix 6.4.0.0 through 6.4.0.6 and 6.3.0.0 through 6.3.0.7 apnotify utility is vulnerable to a code injection due to insufficient validation of user input.
IBM Carbon Charts versions 0.4.0 through 1.27.19 contain a cross-site scripting (XSS) vulnerability in the MeterChart component. The issue arises because the Title.truncateTitle() function unsafely inserts a substring of user-provided label text into the DOM using innerHTML without proper sanitization. This allows remote attackers to execute arbitrary JavaScript in the context of the victim's browser session. The vulnerability has a medium severity rating with a CVSS score of 6.1.
### Affected version / file / line
Version: djust v1.1.4 (latest release, published 2026-09-23). File: python/djust/mcp/server.py:354-433 (MCP tool find_handlers_for_template). Confirmed identical on the commit used for triage, a7e4fafd1667b4db0b1465652d4a63cb17117a07.
### Description
```
@mcp.tool()
def find_handlers_for_template(template_path: str) -> str:
"""
Args:
template_path: Either a logical template name (e.g.
'demos/counter.html' — what you'd pass to `render`) OR
an absolute filesystem path. Both are searched.
"""
...
resolved_path: str | None = None
if os.path.isabs(template_path) and os.path.isfile(template_path):
resolved_path = template_path
else:
... # logical-name resolution via Django's template loader
...
with open(resolved_path, "r", encoding="utf-8", errors="replace") as f:
source = f.read()
handler_names_in_template = sorted({m.group(2) for m in dj_event_attr_re.finditer(source)})
```
When template_path is an absolute path to an existing file, it is used directly, with no confinement to the project/template directories — no realpath() + prefix check, no allowlist. open(resolved_path, ...) then reads the file.
This is inconsistent with the sibling tool in the same file (loaddata, ~line 290-303), which explicitly rejects paths outside the project directory for its own path-like parameter:
```
candidate = os.path.realpath(...)
if base_dir and not candidate.startswith(os.path.realpath(str(base_dir))):
return json.dumps({"error": f"fixture path '{p}' resolves outside the project directory", ...})
```
find_handlers_for_template has no equivalent check for template_path before the open() call.
### Impact
An MCP client with access to this tool (available whenever the Django project is running the MCP server via python manage.py djust_mcp — no separate opt-in flag gates this specific tool beyond that) can read the contents of any file on disk that the process has read permission to and that exists, by passing an absolute path — e.g. /etc/passwd, application .env files, SSH keys, or any other sensitive file reachable by the server process's user.
Mitigating factor (reduces this from High to Medium): the tool does not return the raw file content. It runs one fixed regex (dj-(?:click|submit|change|input|keydown|keyup)\s*=\s*['"]([^'"]+)['"]) against the content and returns only the matched handler-name strings, plus confirmation that the file exists and is readable (an existence/readability oracle on its own, independent of the regex match). If the targeted file happens to contain text matching that HTML-attribute-like pattern (plausible for config files, logs, or any text file with key="value"-shaped content), those substrings are returned in full — so the read is not purely blind, but it is not a general-purpose arbitrary-file-read primitive either.
Proof of Concept / Reproduction
Traced via direct source read; no live Django project was exercised for this report (would require a full djust project scaffold, which was out of scope for this pass — see limitation below).
1. MCP client calls: find_handlers_for_template(template_path="/etc/passwd")
2. server.py ~line 393:
```
if os.path.isabs(template_path) and os.path.isfile(template_path):
resolved_path = template_path
```
resolved_path == "/etc/passwd", unchanged, unconfined
3. server.py ~line 430:
```
with open(resolved_path, "r", encoding="utf-8", errors="replace") as f:
source = f.read()
```
/etc/passwd is now fully read into `source`
4. The regex dj_event_attr_re.finditer(source) is applied to the real
/etc/passwd content. /etc/passwd will not match this specific pattern, so
the response would report an empty handler list plus "file exists and was
read" - which already confirms the path-confinement bypass (compare with
passing a nonexistent absolute path, which correctly returns
"Template file not found").
5. On a target where the absolute path points to a file that DOES contain
text shaped like `dj-click="..."` (e.g. a copied HTML fragment, a stray
config value, or a crafted file placed by the attacker via another
vector), the matched substrings are returned verbatim in the JSON
response - full-content disclosure of just those substrings, not the
whole file.
### Suggested Fix
Apply the same confinement loaddata already uses, before the os.path.isfile check:
```
if os.path.isabs(template_path):
candidate = os.path.realpath(template_path)
if base_dir and not candidate.startswith(os.path.realpath(str(base_dir))):
return json.dumps({
"error": f"template path '{template_path}' resolves outside the project directory",
"resolved": candidate,
"project_dir": str(base_dir),
})
if os.path.isfile(candidate):
resolved_path = candidate
```
### Limitations
Not exercised against a live Django/dju
Enabling the CURLOPT_CRLF option in curl causes it to advertise the raw input byte count in the IMAP APPEND {N} literal while transmitting data with expanded line endings. The IMAP server reads only the specified N bytes for the payload, but any overflow bytes beyond N are interpreted as additional IMAP commands within the authenticated session.
A stack-based buffer overflow vulnerability exists in the boa formTR069Config functionality of the TOTOLINK X2000R device version TOTOLINK-X2000R-Gh-V1.0.0-B20250421.1327. This vulnerability can be triggered by an authenticated HTTP request, potentially allowing arbitrary code execution.
A stack-based buffer overflow vulnerability exists in the boa formUploadFile functionality of the TOTOLINK X2000R device firmware version TOTOLINK-X2000R-Gh-V1.0.0-B20250421.1327. This vulnerability can be triggered by an authenticated HTTP request with specially crafted data, potentially allowing arbitrary code execution. The vulnerability is rated critical with a CVSS score of 9.1.
Multiple stack-based buffer overflow vulnerabilities exist in the boa formFilter functionality of TOTOLINK X2000R firmware version TOTOLINK-X2000R-Gh-V1.0.0-B20250421.1327. These vulnerabilities can be triggered by an authenticated HTTP request manipulating the vpnPassword parameter, potentially allowing arbitrary code execution. The vulnerabilities have a critical severity with a CVSS score of 9.1.
A vulnerability in libcurl causes the curl_easy_getinfo() function with the CURLINFO_EFFECTIVE_URL option to potentially return a URL containing credentials, even though the original or redirected URLs did not include them.
An OS command injection vulnerability (CVE-2026-9814) exists in the boa formWizard newPass functionality of the TOTOLINK X2000R device (version TOTOLINK-X2000R-Gh-V1.0.0-B20250421.1327). This vulnerability allows an authenticated attacker to execute arbitrary code by sending a specially crafted HTTP request. The vulnerability has a high CVSS score of 9.1, indicating critical severity.
An arbitrary file write vulnerability exists in the boa formUploadFile functionality of TOTOLINK X2000R firmware version TOTOLINK-X2000R-Gh-V1.0.0-B20250421.1327. This vulnerability allows an authenticated attacker to send a specially crafted HTTP request that can lead to arbitrary code execution on the device. The vulnerability is critical with a CVSS score of 9.1.
A vulnerability in curl causes it to erroneously retain and resend the original host's HTTP Negotiate authentication state when processing an HTTP redirect to a URL containing userinfo (username:password). This behavior allows a malicious server to force curl to send a freshly minted Kerberos ticket to an untrusted third-party host, bypassing domain-scoping restrictions normally enforced by the absence of the --location-trusted option.
A vulnerability in libcurl when used with libssh2 and a hashed known_hosts file causes host key validation to incorrectly report a key mismatch as a missing key in the SSH key callback.
A vulnerability exists in the handling of HSTS policies where importing a parent domain's includeSubDomains HSTS entry before a longer-lived child domain entry causes the child entry to be silently dropped. This results in the loss of the child's valid HSTS policy when the parent expires, leading curl to downgrade to unencrypted HTTP requests instead of enforcing HTTPS.
CVE-2026-87861 is a vulnerability involving the use of ambient user credentials in HTTP requests. When an HTTP request is sent to one origin, it may be dispatched over a connection previously authenticated for a different origin using Negotiate authentication. This causes the request to use the previously authenticated connection's credentials rather than the intended credentials for the target origin.
A vulnerability in curl causes it to write cookie records exceeding line-length limits when a remote HTTP server sets long cookie names and values in a Netscape cookie jar. This results in subsequent curl invocations silently aborting cookie parsing upon encountering the overly long line, ignoring valid cookies that follow.
CVE-2026-87863 is a vulnerability where an authenticated HTTPS origin can supply an HSTS max-age value that the parser accepts, but later fails during time serialization. On 64-bit systems, extremely large max-age values cause expiry times that exceed calendar time structure limits. This leads to cache save operations truncating the original HSTS file and deleting the temporary replacement file, resulting in an empty or partial HSTS cache. The error is silently ignored, causing curl to exit successfully despite data loss.
A vulnerability in libcurl allows an HTTP proxy to trick libcurl into sending the origin server's credentials, such as Basic authentication passwords or Negotiate/Kerberos tickets, to the proxy itself. This occurs when the proxy responds to a CONNECT tunnel request with a 401 WWW-Authenticate status instead of the expected 407 Proxy-Authenticate status.
A vulnerability in libcurl's TFTP state machine allows a malicious TFTP server to manipulate the client's transfer mode. The state machine does not properly validate state transitions against the requested transfer direction, causing the client to accept server responses for both read and write operations interchangeably. This can lead libcurl to transmit unintended data from a reused handle, potentially leaking data from unrelated prior operations.
A vulnerability in curl occurs when using the --remote-header-name (-J) option. If an intermediate 103 Early Hints response precedes the final HTTP response, or if an ETag header is processed before Content-Disposition under --etag-save, curl fails to enforce its anti-clobbering protection. This allows an HTTP(S) server to overwrite an existing local file despite the intended non-overwrite constraint.
A stack overflow vulnerability exists in libcurl triggered by a deeply nested multipart MIME structure created via the public API. The issue occurs during normal cleanup operations when the function curl_mime_free encounters excessive recursion depth, causing unbounded stack frame allocation and crashing the host process.