Mar 25, 2026·6 min read·27 visits
A stored XSS vulnerability in MantisBT 2.28.0 allows authenticated attackers to execute arbitrary JavaScript in the context of other users viewing the issue timeline by leveraging deleted or renamed tags.
Mantis Bug Tracker (MantisBT) version 2.28.0 contains a stored Cross-Site Scripting (XSS) vulnerability in its Timeline feature. The flaw occurs when the application renders historical issue tags that have been subsequently renamed or deleted, falling back to an unescaped raw string from the database.
Mantis Bug Tracker (MantisBT) version 2.28.0 contains a stored Cross-Site Scripting (XSS) vulnerability tracked as CVE-2026-33548. The vulnerability manifests within the Timeline feature, specifically when rendering historical issue tags. An attacker can inject arbitrary JavaScript that executes when a victim views the timeline on the dashboard (my_view_page.php).
The flaw occurs due to improper output encoding when handling edge cases in the tag history. When an issue tag is modified, the application records the tag's state in the bug_history table. During timeline generation, the application attempts to resolve the historical tag name to an active tag object to generate a safe HTML link.
This vulnerability is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation). It requires low privileges to stage the payload and relies on user interaction to execute. The execution context is the browser session of the victim, which exposes sensitive session tokens and administrative interfaces to the attacker.
The vulnerability is located in the IssueTagTimelineEvent::html() method within core/classes/IssueTagTimelineEvent.class.php. The timeline rendering logic fetches historical tag information from the database to reconstruct the issue's event history. When the timeline is rendered, the system queries the active tags to create a linked representation of the historical event.
If a tag referenced in the history has been deleted or renamed since the history entry was created, the active tag object cannot be found. In this scenario, the application defaults to using the raw, unescaped name string stored in the bug_history table. This fallback variable, $this->tag_name, is directly concatenated into the HTML output.
The absence of HTML entity encoding on this specific fallback path creates the vulnerability. While the primary execution path utilizing tag_get_link() properly sanitizes output, the fallback path assumes the historical data is safe. This violates the principle of context-aware output encoding.
The vulnerability exists in the formatting logic of the html() method. The method utilizes a ternary operator to determine whether to render a rich link or a plain text fallback. The vulnerable code path evaluates $t_tag_row to check for the existence of the tag object.
// Vulnerable Code (Version 2.28.0)
return sprintf(
$t_string,
prepare_user_name( $this->user_id ),
string_get_bug_view_link( $this->issue_id ),
$t_tag_row ? tag_get_link( $t_tag_row ) : $this->tag_name
);The patch applied in version 2.28.1 addresses this by passing the fallback variable through the string_html_specialchars() function. This ensures that any HTML characters within the raw tag name are properly encoded before being inserted into the DOM.
// Patched Code (Commit f32787c14d4518476fe7f05f992dbfe6eaccd815)
- $t_tag_row ? tag_get_link( $t_tag_row ) : $this->tag_name
+ $t_tag_row ? tag_get_link( $t_tag_row ) : string_html_specialchars( $this->tag_name )This fix is complete for this specific code path. It ensures that regardless of whether the tag object exists or the application falls back to the raw database string, the output is neutralized before reaching the browser context.
Exploitation requires an attacker to possess privileges sufficient to create issue tags, typically assigned to the Reporter role or higher. The attacker begins by creating a new tag containing a malicious JavaScript payload within HTML tags. This payload is stored in the application database.
The attacker then attaches this crafted tag to a target issue. This action creates a permanent record in the bug_history table containing the unescaped payload. To arm the exploit, the attacker must force the timeline rendering logic into the vulnerable fallback path.
The attacker achieves this by deleting or renaming the crafted tag. Once the tag object is no longer available, the trigger mechanism is established. Any subsequent visit to the issue timeline or the "My View" dashboard (my_view_page.php) will execute the payload.
The payload executes in the context of the viewing user's browser session. The attacker does not need to maintain any active access once the payload is staged, making this an asynchronous attack that persists in the environment until the specific history entry is removed.
Successful exploitation results in the execution of arbitrary JavaScript within the context of the victim's session. This allows the attacker to perform actions on behalf of the user, including viewing sensitive issue details or modifying platform configurations. If the victim holds administrative privileges, the attacker can achieve full application compromise.
The CVSS v4.0 base score of 8.6 reflects the high impact on confidentiality, integrity, and availability. The attack requires low privileges and user interaction, as the victim must view the specific timeline containing the armed payload. The vulnerability relies on persistent storage, meaning the exploit remains active until the underlying database records are sanitized.
The exploit maps to MITRE ATT&CK techniques T1189 (Drive-by Compromise) and T1185 (Browser Session Hijacking). While the current Exploit Prediction Scoring System (EPSS) score is low at 0.00069, the straightforward nature of the exploit and the availability of the patch diff make weaponization highly probable.
The primary remediation strategy is upgrading MantisBT to version 2.28.1 or later. This release contains the patch that correctly implements output encoding on the vulnerable fallback path. Organizations should prioritize patching systems exposed to untrusted users.
For environments where immediate patching is not feasible, administrators can apply a manual code-level fix. This involves locating the html() function within core/classes/IssueTagTimelineEvent.class.php and wrapping $this->tag_name in a string_html_specialchars() call. This directly replicates the official vendor patch without requiring a full version upgrade.
Administrators can also proactively sanitize existing databases to remove malicious payloads. Executing a SQL query to identify and remove HTML tags from the bug_history table where the field_name is 'tag' will disarm existing exploits. Implementing a strong Content Security Policy (CSP) will provide defense-in-depth against XSS execution.
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N| Product | Affected Versions | Fixed Version |
|---|---|---|
MantisBT mantisbt | 2.28.0 | 2.28.1 |
| Attribute | Detail |
|---|---|
| CWE ID | CWE-79 |
| Attack Vector | Network |
| CVSS v4.0 | 8.6 (High) |
| EPSS Score | 0.00069 |
| Impact | Stored Cross-Site Scripting |
| Exploit Status | None |
| KEV Status | Not Listed |
Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
A security feature bypass vulnerability in the Falco k8saudit plugin (and its cloud-specific variants) allowed privileged workloads to run undetected. This bypass occurred because the plugin's default extraction logic and rules only evaluated standard containers, completely omitting initContainers and ephemeralContainers.
nginx-ignition is a web-based user interface for managing the Nginx web server. In versions 2.33.0 through 2.35.0, the application is vulnerable to an improper authentication flaw (CWE-287) in its Multi-Factor Authentication (MFA) implementation. The stateless validation of Time-Based One-Time Passwords (TOTP) allows an attacker to reuse a captured, active verification code multiple times within the standard 30-second validity window, successfully bypassing secondary authentication checks if primary credentials are known.
A vulnerability exists in the i18n middleware of nginx-ignition, enabling CPU amplification attacks. By transmitting a crafted Accept-Language header containing malformed tags separated by underscores, an unauthenticated remote attacker can bypass the length-guard threshold of the underlying Go parsing library. Normalization of underscores to hyphens occurs after the initial validation checks, forcing the parser into expensive quadratic-time loops that consume 100% of available CPU resources. This leads to a complete denial of service for the administrative API and potentially degrades the availability of the hosting system. This vulnerability has been resolved in version 2.40.1.
Nginx Ignition prior to version 2.41.1 contains a Time-of-Check to Time-of-Use (TOCTOU) race condition in its unauthenticated onboarding API endpoint. This flaw allows remote, unauthenticated attackers to register an administrative account by sending concurrent HTTP requests during the initial system configuration phase, bypassing the check meant to restrict onboarding to a single initial administrator.
A logic error in Hatchet's OAuth state validation mechanism allows unauthenticated remote attackers to bypass state parameter verification. By submitting an empty state parameter, attackers can exploit an equality collision with cleared session keys, facilitating Login Cross-Site Request Forgery (Login CSRF) or Session Fixation.
A high-severity access control vulnerability in ToolHive CLI before v0.30.1 and ToolHive Studio before v0.38.0 allows local containerized MCP servers to bypass network isolation. This enables malicious workloads to establish TCP/IP connections to administrative and control plane endpoints exposed on the host loopback interface.