CVE-2026-77268
MCP Atlassian: Insecure File Permissions on OAuth Token Storage
MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, the OAuth fallback token directory and JSON file are created without explicit owner-only modes. Local users or processes with access through the resulting group or world permission bits can read access and refresh tokens and reuse the associated Atlassian session. The advisory traces the vulnerable input and processing flow through ~/.mcp-atlassian, oauth-<client_id>.json, access_token, and refresh_token, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.
Attack profile
How easy it is to exploit
- Attack vector
- Local
- Complexity
- Low
- Privileges needed
- Low
- User interaction
- None
What an attacker can affect
- Confidentiality
- High
- Integrity
- None
- Availability
- None
Exploit likelihood
What each source reports
CVE List Score used
5.5
MCP Atlassian: Insecure File Permissions on OAuth Token Storage
MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, the OAuth fallback token directory and JSON file are created without explicit owner-only modes. Local users or processes with access through the resulting group or world permission bits can read access and refresh tokens and reuse the associated Atlassian session. The advisory traces the vulnerable input and processing flow through ~/.mcp-atlassian, oauth-<client_id>.json, access_token, and refresh_token, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.
- Record
CVE-2026-77268- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-732
- Updated
- 2026-11-02
EUVDEUVD-2026-84757
5.5
MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, the OAuth fallback token directory and JSON file are created without explicit owner-only modes. Local users or processes with access through the resulting group or world permission bits can read access and refresh tokens and reuse the associated Atlassian session. The advisory traces the vulnerable input and processing flow through ~/.mcp-atlassian, oauth-<client_id>.json, access_token, and refresh_token, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.
- Record
EUVD-2026-84757- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
GitHub AdvisoriesGHSA-4596-2p6p-28cv
5.5
MCP Atlassian: Insecure File Permissions on OAuth Token Storage
Summary
The OAuth token fallback file storage in OAuthConfig._save_tokens_to_file() creates token files containing access tokens, refresh tokens, and cloud IDs with default filesystem permissions (typically 0644 on Linux, world-readable). Any local user on a shared system can read these files to obtain full Atlassian API credentials, enabling unauthorized access to the victim's Jira and Confluence data.
Details
The vulnerability exists in src/mcp_atlassian/utils/oauth.py in the _save_tokens_to_file method.
Step 1 -- Directory created without restrictive permissions:
At line 402-403, the token directory is created with mkdir(exist_ok=True) which uses the default umask (typically creating directories with mode 0755):
# src/mcp_atlassian/utils/oauth.py:402-403
token_dir = Path.home() / ".mcp-atlassian"
token_dir.mkdir(exist_ok=True)
Step 2 -- Token file written with default permissions:
At line 417-418, the token file containing sensitive credentials is written using open() with no explicit mode, inheriting default umask permissions (typically 0644 on Linux):
# src/mcp_atlassian/utils/oauth.py:406-418
token_path = token_dir / f"oauth-{self.client_id}.json"
if token_data is None:
token_data = {
"refresh_token": self.refresh_token,
"access_token": self.access_token,
"expires_at": self.expires_at,
"cloud_id": self.cloud_id,
"base_url": self.base_url,
}
with open(token_path, "w") as f:
json.dump(token_data, f)
Step 3 -- The file contains full API credentials:
The token file contains:
access_token: A valid OAuth access token for the Atlassian APIrefresh_token: Can be exchanged for new access tokens indefinitelycloud_id: Identifies the target Atlassian Cloud instancebase_url: The target Data Center instance URL
No os.chmod or os.fchmod is called anywhere after file creation.
The primary storage via keyring (line 373) is secure, but the fallback file storage at line 386 is always written in addition to keyring (line 386: self._save_tokens_to_file(token_data)). When keyring fails (common in headless/container/CI environments), the fallback becomes the only storage.
PoC
# Step 1: Victim runs mcp-atlassian with OAuth and completes the flow.
# This creates the token file.
# Step 2: As any other user on the same system, read the token file:
cat /home/victim/.mcp-atlassian/oauth-*.json
# Expected output (sensitive credentials in plaintext):
# {"refresh_token": "eyJ...", "access_token": "eyJ...", "expires_at": 1741234567.0, "cloud_id": "abc-123", "base_url": null}
# Step 3: Verify the token works:
curl -H "Authorization: Bearer <stolen_access_token>" \
"https://api.atlassian.com/ex/jira/<stolen_cloud_id>/rest/api/3/myself"
# Step 4: Use the refresh token to get a new access token:
curl -X POST "https://auth.atlassian.com/oauth/token" \
-d "grant_type=refresh_token" \
-d "client_id=<from_env>" \
-d "client_secret=<from_env>" \
-d "refresh_token=<stolen_refresh_token>"
Verify file permissions (on Linux/macOS):
ls -la ~/.mcp-atlassian/
# drwxr-xr-x 2 user user 4096 Mar 10 12:00 .
# -rw-r--r-- 1 user user 256 Mar 10 12:00 oauth-abc123.json
# ^^ ^^ ^^
# world-readable!
Impact
- Credential theft: Any local user can read the OAuth tokens and impersonate the victim on their Atlassian Cloud/Data Center instance.
- Persistent access: The refresh token allows the attacker to generate new access tokens indefinitely, even after the original access token expires.
- Full API access: The stolen tokens grant the same API permissions as the victim, including reading/writing Jira issues, Confluence pages, and potentially sensitive project data.
- Affected environments: Shared servers, CI/CD runners, multi-user workstations, and containerized deployments where the fallback file storage is used (keyring…
- Record
GHSA-4596-2p6p-28cv- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-732
- Updated
- 2026-11-02
NVD
5.5
MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, the OAuth fallback token directory and JSON file are created without explicit owner-only modes. Local users or processes with access through the resulting group or world permission bits can read access and refresh tokens and reuse the associated Atlassian session. The advisory traces the vulnerable input and processing flow through ~/.mcp-atlassian, oauth-<client_id>.json, access_token, and refresh_token, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.
- Record
CVE-2026-77268- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-732
- Updated
- 2026-11-02
OSV
5.5
MCP Atlassian: Insecure File Permissions on OAuth Token Storage
MCP Atlassian is a Model Context Protocol (MCP) server for Atlassian products (Confluence and Jira). Prior to 0.22.0, the OAuth fallback token directory and JSON file are created without explicit owner-only modes. Local users or processes with access through the resulting group or world permission bits can read access and refresh tokens and reuse the associated Atlassian session. The advisory traces the vulnerable input and processing flow through ~/.mcp-atlassian, oauth-<client_id>.json, access_token, and refresh_token, which identify the affected entry points, controls, and code paths. This issue is fixed in version 0.22.0.
- Record
CVE-2026-77268- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-732
- Updated
- 2026-11-02
OSVGHSA-4596-2p6p-28cv
5.5
MCP Atlassian: Insecure File Permissions on OAuth Token Storage
Summary
The OAuth token fallback file storage in OAuthConfig._save_tokens_to_file() creates token files containing access tokens, refresh tokens, and cloud IDs with default filesystem permissions (typically 0644 on Linux, world-readable). Any local user on a shared system can read these files to obtain full Atlassian API credentials, enabling unauthorized access to the victim's Jira and Confluence data.
Details
The vulnerability exists in src/mcp_atlassian/utils/oauth.py in the _save_tokens_to_file method.
Step 1 -- Directory created without restrictive permissions:
At line 402-403, the token directory is created with mkdir(exist_ok=True) which uses the default umask (typically creating directories with mode 0755):
# src/mcp_atlassian/utils/oauth.py:402-403
token_dir = Path.home() / ".mcp-atlassian"
token_dir.mkdir(exist_ok=True)
Step 2 -- Token file written with default permissions:
At line 417-418, the token file containing sensitive credentials is written using open() with no explicit mode, inheriting default umask permissions (typically 0644 on Linux):
# src/mcp_atlassian/utils/oauth.py:406-418
token_path = token_dir / f"oauth-{self.client_id}.json"
if token_data is None:
token_data = {
"refresh_token": self.refresh_token,
"access_token": self.access_token,
"expires_at": self.expires_at,
"cloud_id": self.cloud_id,
"base_url": self.base_url,
}
with open(token_path, "w") as f:
json.dump(token_data, f)
Step 3 -- The file contains full API credentials:
The token file contains:
access_token: A valid OAuth access token for the Atlassian APIrefresh_token: Can be exchanged for new access tokens indefinitelycloud_id: Identifies the target Atlassian Cloud instancebase_url: The target Data Center instance URL
No os.chmod or os.fchmod is called anywhere after file creation.
The primary storage via keyring (line 373) is secure, but the fallback file storage at line 386 is always written in addition to keyring (line 386: self._save_tokens_to_file(token_data)). When keyring fails (common in headless/container/CI environments), the fallback becomes the only storage.
PoC
# Step 1: Victim runs mcp-atlassian with OAuth and completes the flow.
# This creates the token file.
# Step 2: As any other user on the same system, read the token file:
cat /home/victim/.mcp-atlassian/oauth-*.json
# Expected output (sensitive credentials in plaintext):
# {"refresh_token": "eyJ...", "access_token": "eyJ...", "expires_at": 1741234567.0, "cloud_id": "abc-123", "base_url": null}
# Step 3: Verify the token works:
curl -H "Authorization: Bearer <stolen_access_token>" \
"https://api.atlassian.com/ex/jira/<stolen_cloud_id>/rest/api/3/myself"
# Step 4: Use the refresh token to get a new access token:
curl -X POST "https://auth.atlassian.com/oauth/token" \
-d "grant_type=refresh_token" \
-d "client_id=<from_env>" \
-d "client_secret=<from_env>" \
-d "refresh_token=<stolen_refresh_token>"
Verify file permissions (on Linux/macOS):
ls -la ~/.mcp-atlassian/
# drwxr-xr-x 2 user user 4096 Mar 10 12:00 .
# -rw-r--r-- 1 user user 256 Mar 10 12:00 oauth-abc123.json
# ^^ ^^ ^^
# world-readable!
Impact
- Credential theft: Any local user can read the OAuth tokens and impersonate the victim on their Atlassian Cloud/Data Center instance.
- Persistent access: The refresh token allows the attacker to generate new access tokens indefinitely, even after the original access token expires.
- Full API access: The stolen tokens grant the same API permissions as the victim, including reading/writing Jira issues, Confluence pages, and potentially sensitive project data.
- Affected environments: Shared servers, CI/CD runners, multi-user workstations, and containerized deployments where the fallback file storage is used (keyring…
- Record
GHSA-4596-2p6p-28cv- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Weakness
- CWE-732
- Updated
- 2026-11-02
OSVPYSEC-2026-4082
5.5
MCP Atlassian: Insecure File Permissions on OAuth Token Storage
Summary
The OAuth token fallback file storage in OAuthConfig._save_tokens_to_file() creates token files containing access tokens, refresh tokens, and cloud IDs with default filesystem permissions (typically 0644 on Linux, world-readable). Any local user on a shared system can read these files to obtain full Atlassian API credentials, enabling unauthorized access to the victim's Jira and Confluence data.
Details
The vulnerability exists in src/mcp_atlassian/utils/oauth.py in the _save_tokens_to_file method.
Step 1 -- Directory created without restrictive permissions:
At line 402-403, the token directory is created with mkdir(exist_ok=True) which uses the default umask (typically creating directories with mode 0755):
# src/mcp_atlassian/utils/oauth.py:402-403
token_dir = Path.home() / ".mcp-atlassian"
token_dir.mkdir(exist_ok=True)
Step 2 -- Token file written with default permissions:
At line 417-418, the token file containing sensitive credentials is written using open() with no explicit mode, inheriting default umask permissions (typically 0644 on Linux):
# src/mcp_atlassian/utils/oauth.py:406-418
token_path = token_dir / f"oauth-{self.client_id}.json"
if token_data is None:
token_data = {
"refresh_token": self.refresh_token,
"access_token": self.access_token,
"expires_at": self.expires_at,
"cloud_id": self.cloud_id,
"base_url": self.base_url,
}
with open(token_path, "w") as f:
json.dump(token_data, f)
Step 3 -- The file contains full API credentials:
The token file contains:
access_token: A valid OAuth access token for the Atlassian APIrefresh_token: Can be exchanged for new access tokens indefinitelycloud_id: Identifies the target Atlassian Cloud instancebase_url: The target Data Center instance URL
No os.chmod or os.fchmod is called anywhere after file creation.
The primary storage via keyring (line 373) is secure, but the fallback file storage at line 386 is always written in addition to keyring (line 386: self._save_tokens_to_file(token_data)). When keyring fails (common in headless/container/CI environments), the fallback becomes the only storage.
PoC
# Step 1: Victim runs mcp-atlassian with OAuth and completes the flow.
# This creates the token file.
# Step 2: As any other user on the same system, read the token file:
cat /home/victim/.mcp-atlassian/oauth-*.json
# Expected output (sensitive credentials in plaintext):
# {"refresh_token": "eyJ...", "access_token": "eyJ...", "expires_at": 1741234567.0, "cloud_id": "abc-123", "base_url": null}
# Step 3: Verify the token works:
curl -H "Authorization: Bearer <stolen_access_token>" \
"https://api.atlassian.com/ex/jira/<stolen_cloud_id>/rest/api/3/myself"
# Step 4: Use the refresh token to get a new access token:
curl -X POST "https://auth.atlassian.com/oauth/token" \
-d "grant_type=refresh_token" \
-d "client_id=<from_env>" \
-d "client_secret=<from_env>" \
-d "refresh_token=<stolen_refresh_token>"
Verify file permissions (on Linux/macOS):
ls -la ~/.mcp-atlassian/
# drwxr-xr-x 2 user user 4096 Mar 10 12:00 .
# -rw-r--r-- 1 user user 256 Mar 10 12:00 oauth-abc123.json
# ^^ ^^ ^^
# world-readable!
Impact
- Credential theft: Any local user can read the OAuth tokens and impersonate the victim on their Atlassian Cloud/Data Center instance.
- Persistent access: The refresh token allows the attacker to generate new access tokens indefinitely, even after the original access token expires.
- Full API access: The stolen tokens grant the same API permissions as the victim, including reading/writing Jira issues, Confluence pages, and potentially sensitive project data.
- Affected environments: Shared servers, CI/CD runners, multi-user workstations, and containerized deployments where the fallback file storage is used (keyring…
- Record
PYSEC-2026-4082- CVSS 3.1
- 5.5 Medium
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N - Updated
- 2026-11-02
Affected products
Affected packages
| Package | Affected | Fixed |
|---|---|---|
mcp-atlassianPyPI |
before 0.22.0 | 0.22.0 |
mcp-atlassianPyPI |
before 0.22.0, plus listed versions 0.1.10.1.100.1.110.1.120.1.13 Show 45 moreShow less0.1.140.1.150.1.160.1.20.1.30.1.40.1.60.1.70.1.80.1.90.10.00.10.10.10.20.10.30.10.40.10.50.10.60.11.00.11.10.11.100.11.110.11.120.11.20.11.2a20.11.30.11.40.11.50.11.60.11.70.11.80.11.90.12.00.13.00.13.10.14.00.14.10.14.20.14.30.15.00.16.00.16.10.17.00.18.00.18.10.19.0 |
0.22.0 |
History
| Recorded | Changed | Sources |
|---|---|---|
| first indexed | CVE List, EUVD, GitHub Advisories, NVD, OSV |
Dates are when Every CVE recorded each change. Upstream dates may differ.
In short
CVE-2026-77268 is a medium vulnerability (CVSS 5.5) in Mcp-atlassian Mcp Atlassian, published September 22, 2026. No source lists public exploit code. EPSS puts the chance of exploitation in the next 30 days at 0.15%, the 4th percentile. Fixed in mcp-atlassian 0.22.0.
References
github.com/sooperset/mcp-atlassian/security/advisories/GHSA-4596-2p6p-28cv
github.com/sooperset/mcp-atlassian/pull/1448
github.com/sooperset/mcp-atlassian/commit/b041733473f95119dd539542a43c280737a8e460
github.com/sooperset/mcp-atlassian/releases/tag/v0.22.0
github.com/advisories/GHSA-4596-2p6p-28cv
github.com/CVEProject/cvelistV5/tree/main/cves/2026/77xxx/CVE-2026-77268.json
nvd.nist.gov/vuln/detail/CVE-2026-77268
github.com/sooperset/mcp-atlassian
pypi.org/project/mcp-atlassian
Left out here: 29 versions and the rest of 3 source descriptions. The JSON record has them.