Skip to content

GHSA-w66g-j6c4-hcfc CVE-2026-77251 PYSEC-2026-4102

MCP Atlassian: JIRA_PROJECTS_FILTER / CONFLUENCE_SPACES_FILTER allow forbidden-project content exfiltration (one LIVE-proven on Atlassian Cloud)

Medium PyPI
Severity
0.0 / 10
Medium ยท CVSS 4.0
Exploit chance (EPSS)
0.27%
Chance of exploitation in the next 30 days. Higher than 18.52% of scored vulnerabilities.
Known exploited
No
Not in CISA's catalog
Weakness
CWE-1276 Hardware Child Block Incorrectly Connected to Parent System
CWE-184 Incomplete List of Disallowed Inputs
CWE-693 Protection Mechanism Failure
CWE-863 Incorrect Authorization
Fix
0.22.0
Upgrade mcp-atlassian to this version or later

Description

Summary

mcp-atlassian is a popular community MCP server wrapper exposing Jira / Confluence to MCP clients. Operators commonly restrict the surface to a small allowlist of projects/spaces via the JIRA_PROJECTS_FILTER and CONFLUENCE_SPACES_FILTER environment variables, which the README documents as the principal mechanism for limiting attacker-controlled MCP clients (= prompt-injected LLM agents) to the operator's intended subset of the workspace.

We identified three distinct sub-bugs that let attacker-controlled queries read content from forbidden projects/spaces (= projects NOT in the operator's filter) despite the filter being correctly set. The most severe is empirically reproduced on production Atlassian Cloud with real operator credentials and sentinel content in two real projects.

Sub-bug Layer Class Live?
A1 Jira jira_search jql substring-bypass ๐Ÿ”ด LIVE PROVEN 2026-05-18 on real Atlassian Cloud
A2 Confluence confluence_search cql case-sensitive substring-bypass code-level verified
B Jira agile get_board_issues / get_agile_boards zero-filter (missing check) code-level verified

Details

Sub-bug A1 โ€” src/mcp_atlassian/jira/search.py lines 92-94 at HEAD d8bc78698a63cb6b321c7ca796d6329d448f7f6d:

if projects_filter and "project = " not in jql.lower():
    jql = f"{jql} AND project in ({','.join(projects_filter)})"

The substring check is satisfied by any JQL of the form project = <forbidden-project> โ€” including a project NOT in projects_filter. The wrapper does NOT verify that the project named in the user JQL is a member of the allowlist. The user-supplied JQL is sent verbatim to Jira's search API which returns content from the forbidden project (Jira's authorization is satisfied because the operator's PAT typically has broader access than the operator's intended allowlist โ€” which is why the operator set a filter in the first place).

Sub-bug A2 โ€” src/mcp_atlassian/confluence/search.py line 60: same pattern as A1, PLUS the substring check "space = " not in cql is case-sensitive (no .lower()). User CQL SPACE = "<forbidden-space>" (uppercase) bypasses the substring match.

Sub-bug B โ€” get_board_issues and get_agile_boards paths have no projects_filter enforcement at all โ€” no substring check, no AST walk, the allowlist is silently ignored. An MCP client invoking get_agile_boards enumerates boards across the entire workspace (including forbidden projects), and get_board_issues(boardId=<forbidden-board>) returns all issues with no filter check.

PoC

End-to-end Phase C against real Atlassian Cloud + real mcp-atlassian Python binary v0.21.1 (latest on PyPI) with operator-provided test workspace and two real Jira projects (one allowed, one forbidden via JIRA_PROJECTS_FILTER):

Step JQL submitted Result Verdict
1 initialize โ€“ MCP 2024-11-05 OK โœ“
2 tools/list โ€“ 33+ tools incl. jira_search โœ“
3 CONTROL project = <allowed> returns allowed issue โœ“
4 NEG CTRL summary ~ "any-string" wrapper appends AND project in (<allowed>) โ†’ 0 forbidden results โœ“
5 BYPASS A1 project = <forbidden> returns forbidden issue with sentinel content ๐Ÿ”ด BYPASS

Full RPC log and a reproducible test script are available in a disclosure bundle I have prepared. I can share the zip via a private channel (email / your preferred private fork / encrypted upload) โ€” please reply with your preference. The bundle includes:

  • 00-FINDING-REPORT.md (primary report)
  • ATTACK-MATRIX.md
  • Verbatim source files at HEAD with sha256 chain of custody (source-jira-search.py, source-confluence-search.py)
  • Phase C live test script + JSON-RPC witness log
  • Bundle zip sha256: 034cbf0bcb66c325be9373ff2dc186b8b0e1747c5165d6fba3bca83054949dd3

Repro recipe (no bundle needed) :

pip install mcp-atlassian
export JIRA_URL=https://<your-test-workspace>.atlassian.net
export JIRA_USERNAME=<your-test-email>
export JIRA_API_TOKEN=<your-pat>
export JIRA_PROJECTS_FILTER=<your-allowed-project-key>
# Then drive the MCP via stdio JSON-RPC with tools/call jira_search jql="project = <forbidden-project-key>"
# Expect: forbidden project content returned despite the filter.

Impact

Severity is higher in deployments where the operator's PAT covers a broader set of projects than JIRA_PROJECTS_FILTER (= the common configuration, which is the reason operators set the filter).

Affected: every operator who relies on JIRA_PROJECTS_FILTER / CONFLUENCE_SPACES_FILTER to confine an attacker-controlled MCP client (= prompt-injected LLM agent) to a subset of their workspace.

Suggested fix

  1. Replace substring checks with AST-based JQL/CQL parsers that walk the WHERE clause looking for project/space constraints. Reject queries whose project/space constraint references a key not in the allowlist.
  2. Add projects_filter check inside get_board_issues (resolve board โ†’ project, reject if not in filter) and get_agile_boards (filter returned list).
  3. Make the Confluence substring check case-insensitive (cql.lower()) for defense-in-depth, even after the AST fix lands.
  4. Default-deny for ambiguous queries: if the AST parser can't fully classify a clause, refuse instead of pass-through.
  5. Add unit tests that assert attacker JQL project = <not-in-filter> returns zero results when the filter is set.

Disclosure

ISO/IEC 29147. Default 90-day embargo from the date you acknowledge receipt. Happy to coordinate the CVE via the GitHub CNA pipeline. Credit under: Mordehai Attia, Founder, Corsen AI (https://corsen.ai , GitHub @CorsenAI).

Thank you for maintaining mcp-atlassian โ€” the project is widely used and your security policy was clear, which made this disclosure straightforward to file. Looking forward to coordinating the fix.

Affected versions

PyPI

PackageVulnerableFixed in
mcp-atlassian
< 0.22.0
0.22.0

How to fix

Move to the fixed version or later with your package manager, update the lockfile, and run your tests. If the package only arrives through another dependency, upgrade that dependency first. If none of its releases pulls a fixed version yet, force the version with your package manager's override.

mcp-atlassian PyPI โ†’ 0.22.0

pip
pip install --upgrade "mcp-atlassian>=0.22.0"
poetry
poetry add "mcp-atlassian>=0.22.0"
uv
uv add "mcp-atlassian>=0.22.0"

Severity breakdown

CVSS 4.0 0.0

CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:N/VC:H/VI:N/VA:N/SC:H/SI:N/SA:N

Attack vector
Network
Attack complexity
Low
Attack requirements
None
Privileges required
Low
User interaction
None
Confidentiality (vulnerable system)
High
Integrity (vulnerable system)
None
Availability (vulnerable system)
None
Confidentiality (subsequent systems)
High
Integrity (subsequent systems)
None
Availability (subsequent systems)
None

CVSS 3.1 6.5

CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
None
Scope
Unchanged
Confidentiality
High
Integrity
None
Availability
None

Weakness

CWE-1276: Hardware Child Block Incorrectly Connected to Parent System

Signals between a hardware IP and the parent system design are incorrectly connected causing security risks.

How to prevent it
  • Testing: System-level verification may be used to ensure that components are correctly connected and that design security requirements are not violated due to interactions between various IP blocks.

CWE-184: Incomplete List of Disallowed Inputs

The product implements a protection mechanism that relies on a list of inputs (or properties of inputs) that are not allowed by policy or otherwise require other action to neutralize before additional processing takes place, but the list is incomplete.

How to prevent it
  • Implementation: Do not rely exclusively on detecting disallowed inputs. There are too many variants to encode a character, especially when different environments are used, so there is a high likelihood of missing some variants. Only use detection of disallowed inputs as a mechanism for detecting suspicious activity. Ensure that you are using other protection mechanisms that only identify "good" input - such as lists of allowed inputs - and ensure that you are properly encoding your outputs.

CWE-693: Protection Mechanism Failure

The product does not use or incorrectly uses a protection mechanism that provides sufficient defense against directed attacks against the product.

CWE-863: Incorrect Authorization

The product performs an authorization check when an actor attempts to access a resource or perform an action, but it does not correctly perform the check.

How to prevent it
  • Architecture and Design: Divide the product into anonymous, normal, privileged, and administrative areas. Reduce the attack surface by carefully mapping roles with data and functionality. Use role-based access control (RBAC) [REF-229] to enforce the roles at the appropriate boundaries. Note that this approach may not protect against horizontal authorization, i.e., it will not protect a user from attacking others with the same role.
  • Architecture and Design: Ensure that access control checks are performed related to the business logic. These checks may be different than the access control checks that are applied to more generic resources such as files, connections, processes, memory, and database records. For example, a database may restrict access for medical records to a specific database user, but each record might only be intended to be accessible to the patient and the patient's doctor [REF-7].
  • Architecture and Design: Use a vetted library or framework that does not allow this weakness to occur or provides constructs that make this weakness easier to avoid. For example, consider using authorization frameworks such as the JAAS Authorization Framework [REF-233] and the OWASP ESAPI Access Control feature [REF-45].
  • Architecture and Design: For web applications, make sure that the access control mechanism is enforced correctly at the server side on every page. Users should not be able to access any unauthorized functionality or information by simply requesting direct access to that page. One way to do this is to ensure that all pages containing sensitive information are not cached, and that all such pages restrict access to requests that are accompanied by an active and authenticated session token associated with a user who has the required permissions to access that page.
  • System Configuration, Installation: Use the access control capabilities of your operating system and server environment and define your access control lists accordingly. Use a "default deny" policy when defining these ACLs.

References

Timeline

  1. Published
  2. Last updated by the source
  3. Latest EPSS score
AdvisorySeverityWhy it's related
GHSA-g2r2-3j32-j27x
MCP Atlassian: Reflected XSS in OAuth Setup Callback Handler
Medium Also affects mcp-atlassian
GHSA-h7wj-5v37-59r2
MCP Atlassian: Path traversal in upload_attachment allows arbitrary file read (incomplete fix for CVE-2026-27825)
Medium Also affects mcp-atlassian
GHSA-4596-2p6p-28cv
MCP Atlassian: Insecure File Permissions on OAuth Token Storage
Medium Also affects mcp-atlassian
GHSA-mfv2-4wvm-9pgp
MCP Atlassian: Path traversal in upload_attachment allows arbitrary file read and exfiltration via MCP tool call
Medium Also affects mcp-atlassian
GHSA-p6hp-93wp-fh6p
MCP Atlassian: Path Traversal / Arbitrary File Read in confluence_upload_attachment MCP tool (incomplete fix of GHSA-xjgw-4wvw-rgm4)
High Also affects mcp-atlassian
GHSA-6cr4-ccf3-x7h4
MCP Atlassian: Arbitrary file read via confluence_upload_attachment allows exfiltration of server credentials
High Also affects mcp-atlassian
GHSA-mrq8-fv7v-hhjg
MCP Atlassian: HTTP upload tools accept arbitrary server-local file paths
Medium Also affects mcp-atlassian
GHSA-2xj6-xx86-cwwc
MCP Atlassian: Arbitrary File Read & Exfiltration (Confused Deputy) in JIRA update_issue
High Also affects mcp-atlassian
Is this in your code?

MergeHarbor checks every repository's dependencies against this database, ranks what matters by exploitability and reachability, routes it to the owning team and opens the fix pull request.

Check your repos with MergeHarbor