Mittel

MCP Atlassian: Insecure File Permissions on OAuth Token Storage

  • Veröffentlicht: 22.09.2026
  • Aktualisiert: 11.10.2026 15:18

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):

python
# 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):

python
# 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 API
  • refresh_token: Can be exchanged for new access tokens indefinitely
  • cloud_id: Identifies the target Atlassian Cloud instance
  • base_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

bash
# 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):

bash
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 unavailable).

Recommended Fix

1. Set restrictive permissions on the directory and file:

python
# src/mcp_atlassian/utils/oauth.py

import os
import stat

def _save_tokens_to_file(self, token_data: dict | None = None) -> None:
    """Save the tokens to a file as fallback storage."""
    try:
        token_dir = Path.home() / ".mcp-atlassian"
        token_dir.mkdir(exist_ok=True, mode=0o700)

        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,
            }

        # Open with restrictive permissions (owner-only read/write)
        fd = os.open(
            str(token_path),
            os.O_WRONLY | os.O_CREAT | os.O_TRUNC,
            stat.S_IRUSR | stat.S_IWUSR,  # 0o600
        )
        try:
            with os.fdopen(fd, "w") as f:
                json.dump(token_data, f)
        except Exception:
            os.close(fd)
            raise

        logger.debug(f"Saved OAuth tokens to file {token_path} (fallback storage)")
    except Exception as e:
        logger.error(f"Failed to save tokens to file: {e}")

2. Additionally, fix the directory permissions for existing installations:

python
# In __init__ or from_env, ensure existing directories are tightened
token_dir = Path.home() / ".mcp-atlassian"
if token_dir.exists():
    os.chmod(str(token_dir), 0o700)

Betroffene Software

Klicken Sie auf eine Technologie, um alle zugehörigen Schwachstellen anzuzeigen.

PlattformPaketAnfällige VersionenBehoben in
Python (PyPI) mcp-atlassian < 0.22.0 0.22.0

Verweise

CVSS-Wert 5.5/10
CVSS-Vektor
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:N
Schwäche (CWE)
CWE-732
Plattform
Python (PyPI)
Paket
mcp-atlassian
Veröffentlicht
22.09.2026
Aktualisiert
11.10.2026 15:18

Quellen und Lizenzen

OSV / GitHub Advisory Database - PYSEC-2026-4082 - PyPA Advisory Database; CC BY 4.0

OSV / GitHub Advisory Database - GHSA-4596-2p6p-28cv - CC BY 4.0

Schwachstellenhistorie: mcp-atlassian

Alle veröffentlichten Schwachstellen dieses Pakets (Python (PyPI)), neueste zuerst. Zeigt, ob es ein einmaliger Ausrutscher ist oder ein Paket, das man im Auge behalten muss.

Alle (30) im Archiv
Einträge insgesamt
30
Erste → letzte
03.2026 09.2026
Ohne Fix
0
In Angriffen ausgenutzt
0

Verteilung nach Schweregrad

  • Kritisch 2
  • Hoch 19
  • Mittel 9

Veröffentlichungen pro Jahr

  1. 2026: 30
Schweregrad:
  1. Hoch CVE-2026-77274 < 0.22.0 0.22.0
  2. Hoch CVE-2026-77267 < 0.22.0 0.22.0
  3. MCP Atlassian: Insecure File Permissions on OAuth Token Storage dieser Eintrag
    Mittel · 5.5 CVE-2026-77268 < 0.22.0 0.22.0
  4. Hoch · 8.8 CVE-2026-77243 < 0.22.0 0.22.0

Erkennen Sie Schwachstellen in Ihrer Anwendung

Mit der DockRay-Integration und aktivierter Softwareinventarisierung prüft DockRay gemeldete Komponentenversionen auf bekannte Schwachstellen und benachrichtigt Sie über bestätigte Treffer. Die Abdeckung hängt von der unterstützten Technologie und den verfügbaren Meldungen ab.

Anwendung verbinden
DockRay Newsletter

Anwendungssicherheit in Ihrem Postfach

Wichtige Schwachstellen, konkrete Empfehlungen und praktische Tipps für Ihre Anwendungen. Wählen Sie Ihre Technologien und verfolgen Sie, was für Ihr Projekt relevant ist.

  • Eine tägliche Zusammenfassung neuer Schwachstellen, auch kritischer.
  • Benachrichtigungen über wichtige Updates.
  • Praktische Tipps zur Sicherheit und Überwachung von Anwendungen.

Leer lassen, um Meldungen zu allen Technologien zu erhalten.

Kostenlos anmelden. In jeder E-Mail mit einem Klick abmelden.