Feb 14, 2026·6 min read·35 visits
The Mattermost Jira Plugin failed to verify user permissions when creating Jira issues from Mattermost posts. An attacker with a valid Post ID can force the plugin to retrieve and display content from private channels they cannot access. Fixed in version 11.3.0 and patch releases.
Mattermost is the fortress of secure collaboration, and Jira is the labyrinth of project management. When you bridge the two, you expect a secure tunnel, not a porous sieve. CVE-2026-22892 is a classic authorization bypass within the Mattermost Jira Plugin that allows users to peek into channels they don't belong to. By exploiting a missing permission check in the issue creation workflow, an authenticated user can retrieve post content and attachments from private channels—provided they can guess or acquire the target Post ID. It's a textbook case of the 'Confused Deputy' problem, where a privileged plugin unwittingly does the dirty work for an unprivileged user.
We all love ChatOps. The idea that you can create a Jira ticket directly from a Mattermost rant is the peak of developer efficiency. You see a bug reported in the #ops-nightmare channel, you click a button, and boom—it's in the backlog. It’s seamless. It’s productive. And apparently, it was a little too open.
Enter the Mattermost Jira Plugin. Like most plugins in the Mattermost ecosystem, it acts as a bridge between the chat server and external services. To do its job, the plugin needs to read messages, grab attachments, and format them for Jira. The problem arises when the plugin forgets who it's working for. It runs with system-level privileges to fetch data, but it interacts with users who definitely do not have system-level privileges.
CVE-2026-22892 is the story of what happens when that bridge assumes that just because you asked to cross, you're allowed to cross. It’s a classic failure to validate the authorization context, turning a productivity feature into a potential peep-hole for internal snoops.
The vulnerability lies in the /create-issue API endpoint. When a user decides to turn a message into a Jira issue, the frontend sends a request to the plugin backend containing the post_id of the message. The plugin's job is to fetch that message, extract the text and any file attachments, and present a modal to the user so they can finalize the Jira ticket.
Here is where the logic went off the rails. The plugin utilized its own elevated service privileges to query the Mattermost database for the post_id. The database, recognizing the plugin as a trusted entity, happily handed over the data—regardless of whether the post was in a public channel, a private group, or a direct message between the CEO and the Lawyer.
The plugin then took this sensitive data and returned it to the requesting user's browser to populate the 'Create Issue' form. The missing step? Checking if the requesting user actually had read access to the channel where post_id lived. The plugin acted as a 'Confused Deputy'—a privileged entity tricked into misusing its authority to serve an unauthorized request.
Let's look at the logic flow. In the vulnerable version, the handler for creating an issue looked something like this (simplified for dramatic effect):
// VULNERABLE LOGIC
func (p *Plugin) handleCreateIssue(w http.ResponseWriter, r *http.Request) {
// 1. Get the target Post ID from the request
postID := r.URL.Query().Get("post_id")
// 2. Fetch the post using the Plugin's API interface
// Note: This often bypasses user-level checks if not scoped correctly
post, err := p.API.GetPost(postID)
if err != nil {
http.Error(w, "Post not found", 404)
return
}
// 3. Return the post content to the user so they can edit the Jira ticket
// OOPS: We never checked if 'r.Header.Get("Mattermost-User-ID")' is allowed to see 'post'
json.NewEncoder(w).Encode(post)
}The fix, applied in commit 99ffe20, introduces a mandatory permission check before returning any data. It explicitly verifies that the user making the request has ReadChannel permissions for the channel the post resides in.
// PATCHED LOGIC
func (p *Plugin) handleCreateIssue(w http.ResponseWriter, r *http.Request) {
postID := r.URL.Query().Get("post_id")
userID := r.Header.Get("Mattermost-User-ID") // The actual human
// 1. Fetch the post
post, err := p.API.GetPost(postID)
if err != nil { ... }
// 2. THE FIX: Check permissions explicitly
// Does 'userID' have permission to read 'post.ChannelId'?
if !p.API.HasPermissionToChannel(userID, post.ChannelId, model.PERMISSION_READ_CHANNEL) {
http.Error(w, "Forbidden: You cannot access this post", 403)
return
}
// 3. Proceed only if authorized
json.NewEncoder(w).Encode(post)
}It’s a subtle change—just a few lines of code—but it marks the difference between a secure application and a data leak.
Exploiting this isn't as simple as incrementing an ID counter (thankfully, Mattermost uses 26-character alphanumeric KSUID-style IDs, not integers). You can't just loop from id=1 to id=1000. However, 'Security by Obscurity' is not a valid defense.
The Attack Scenario:
post_id. Even if the admin kicks the unauthorized users from the private channel, that post_id is now known.POST /plugins/jira/api/v2/create-issue?post_id=THE_SECRET_POST_ID HTTP/1.1
Host: mattermost.corp.local
Cookie: MMUSERID=attacker_session"Simpsons, we need to talk about the layoffs...") and links to file attachments.While the CVSS score is a modest 4.3 due to the difficulty of obtaining that ID, the impact if an ID is known is total confidentiality loss for that specific message. This is particularly dangerous for 'Insider Threat' scenarios where a user might have retained IDs from a channel they were recently removed from.
Why does a 4.3 Medium severity matter? Because context is king. In corporate environments, Mattermost is often the repository of the most sensitive, ephemeral data: credentials pasted in haste, HR discussions about terminations, or legal strategies.
If an attacker (perhaps a disgruntled employee) has access to a log file, a screenshot, or a browser history that reveals the post_id of a sensitive discussion, this vulnerability allows them to bypass the channel membership restrictions entirely. They don't need to be in the room to hear the conversation; they just need to know the room number.
Furthermore, this bypasses the fundamental promise of 'Private' channels. It erodes trust in the platform. If a user is removed from a channel, they expect their access to cease immediately. This vulnerability allowed a 'zombie' access pattern where knowledge of the metadata (the ID) granted access to the data.
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N| Product | Affected Versions | Fixed Version |
|---|---|---|
Mattermost Jira Plugin Mattermost | 10.11.0 - 10.11.9 | 10.11.10 |
Mattermost Jira Plugin Mattermost | 11.1.0 - 11.1.2 | 11.1.3 |
Mattermost Jira Plugin Mattermost | < 11.3.0 | 11.3.0 |
| Attribute | Detail |
|---|---|
| CWE | CWE-863 (Incorrect Authorization) |
| CVSS v3.1 | 4.3 (Medium) |
| Attack Vector | Network (Authenticated) |
| Privileges Required | Low (User) |
| EPSS Score | 0.01% (Low) |
| Exploit Status | None (No Public Exploit) |
The software does not perform or incorrectly performs an authorization check when an actor attempts to access a resource or perform an action.
Netflix Lemur before 1.9.3 contains a missing authorization vulnerability (CWE-862, CWE-639) when handling certificate creation, upload, or modification. Authenticated non-read-only users can manipulate the replaces parameter to silence expiration notifications and hijack certificate rotation tasks for arbitrary targets, leading to unauthorized TLS certificate deployment and traffic interception.
CVE-2026-71317 is a critical Broken Object-Level Authorization (BOLA) / Missing Authorization vulnerability in Netflix Lemur versions prior to 1.9.3. When the self-service authority creation option is enabled (ADMIN_ONLY_AUTHORITY_CREATION = False), Lemur allows authenticated non-read-only users to request the creation of a subordinate Certificate Authority (sub-CA) chained to any internal parent authority, even if the requesting user lacks administrative or usage permissions over that parent CA. This allows attackers to generate subordinate CAs signed by trusted root certificates, exposing private keys and compromising the organizational PKI trust chain.
Netflix Lemur, a TLS/SSL certificate management framework, contains a missing authorization check in its certificate export endpoint. Prior to version 1.9.3, the validation logic verifying whether a user had permission to export a certificate was incorrectly placed inside a block that executed only if the selected plugin required a private key. When an authenticated user attempted to export a certificate using a plugin that did not require the private key, the authorization check was bypassed, allowing unauthorized access to the public portions of the certificate and producing misleading audit logs.
A critical security flaw in LibreNMS allows authenticated administrators to execute arbitrary commands by modifying the configured binary path for snmpget and accessing the About page. This occurs due to insufficient verification of the executable file's identity and integrity prior to executing it with shell_exec.
LibreNMS versions prior to 26.7.0 are vulnerable to a stored Cross-Site Scripting (XSS) vulnerability. An authenticated administrator can inject arbitrary HTML or JavaScript into graph descriptions via specific administrative configuration endpoints. When another authenticated user views the affected graph, the unescaped payload executes within their browser context.
An injection vulnerability in LibreNMS's Oxidized integration component allows administrative or network-positioned attackers to achieve stored cross-site scripting (XSS). By setting a malicious oxidized.url endpoint, the server makes outbound queries and processes returned JSON fields containing malicious HTML or JavaScript. These payloads are outputted directly in the web UI without appropriate output encoding.