CVE-2025-64753
Executive Summary
CVE-2025-64753 is an information disclosure vulnerability in Grist-core, a spreadsheet hosting server. Prior to version 1.7.7, a user with only partial read access to a document could still access endpoints listing hashes for versions of that document and receive a full list of changes between versions, even if those changes contained cells, columns, or tables to which the user was not supposed to have read access. This vulnerability allows an attacker to bypass access controls and view sensitive document history. The vulnerability has a CVSS score of 5.3 (Medium) and is classified as CWE-200 (Exposure of Sensitive Information to an Unauthorized Actor). No public exploit code or proof-of-concept is currently available.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Supply Chain & Package Security
Grist-core is an open-source project distributed via GitHub and potentially as a Docker image. The vulnerability is in the application code itself, not in a dependency. However, users should ensure they are using the latest patched version (1.7.7 or later) to mitigate this risk. The package is not distributed via NPM, PyPI, Go, or Ruby registries.
CVSS Breakdown & Threat Level
- CVSS Score: 5.3 (Medium)
- Vector: CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:L/I:N/A:N
- Attack Vector: Network
- Attack Complexity: Low
- Privileges Required: Low (partial read access)
- User Interaction: None
- Scope: Unchanged
- Confidentiality Impact: Low (exposure of document history)
- Integrity Impact: None
- Availability Impact: None
The threat level is considered Medium due to the low complexity and network-based attack vector, but the impact is limited to information disclosure.
Deep Dive & Mechanics
The vulnerability resides in the /compare endpoint of Grist-core. This endpoint is designed to allow users to compare different versions of a document. However, the access control check was insufficient. A user with only partial read access (e.g., access to only certain tables or columns) could still call the /compare endpoint and receive a full list of changes between versions. This includes changes to cells, columns, or tables that the user should not have been able to see.
The root cause is that the authorization logic for the /compare endpoint only checked if the user had any read access to the document, rather than verifying that they had full read access to all parts of the document being compared. This allowed a user with limited permissions to enumerate version hashes and then retrieve the full diff between any two versions.
Vulnerable vs. Patched Code
Vulnerable Code (prior to 1.7.7):
The /compare endpoint likely had a check similar to:
// Vulnerable: Only checks if user has any read access
if (!user.hasReadAccess(docId)) {
return res.status(403).send('Forbidden');
}
// Proceeds to return full diff
Patched Code (version 1.7.7):
The fix restricts the /compare endpoint to users with full read access:
// Patched: Checks for full read access
if (!user.hasFullReadAccess(docId)) {
return res.status(403).send('Forbidden');
}
// Proceeds to return full diff
The exact code changes can be found in the Grist-core repository commit history for version 1.7.7.
Exploitation & Lab Setup
Red Team
Prerequisites:
- A Grist-core instance running version < 1.7.7
- A user account with partial read access to a document (e.g., access to only one table)
Exploitation Steps:
- Authenticate as the user with partial read access.
- Enumerate document versions by calling the
/statesendpoint:curl -X GET "https://target-grist-instance/api/docs/{docId}/states" -H "Authorization: Bearer {token}" - Use the
/compareendpoint to get the full diff between two versions:curl -X GET "https://target-grist-instance/api/docs/{docId}/compare?from={state1}&to={state2}" -H "Authorization: Bearer {token}" - The response will contain all changes, including those to restricted cells, columns, or tables.
Blue Team
Detection:
- Monitor for unusual access to the
/compareendpoint by users with limited permissions. - Look for patterns where a user with partial access is making multiple
/comparerequests. - Alert on any access to
/compareby users who do not have full read access to the document.
Hunting:
- Review logs for the
/compareendpoint and correlate with user permissions. - Check for users who have been granted partial access but are accessing version history.
Indicators of Compromise (IOCs)
- Network: HTTP requests to
/api/docs/{docId}/comparefrom users with partial read access. - Logs: Access log entries showing
GET /api/docs/{docId}/comparewith a 200 response for users who should not have full read access. - File: No specific file-based IOCs.
Detection Engineering
YARA Rule
rule CVE_2025_64753_Grist_Compare_Endpoint {
meta:
description = "Detects exploitation attempts of CVE-2025-64753 by monitoring for unauthorized access to the /compare endpoint"
author = "Valters IT"
date = "2025-04-10"
reference = "CVE-2025-64753"
strings:
$s1 = "/compare" ascii wide nocase
$s2 = "states" ascii wide nocase
$s3 = "fullReadAccess" ascii wide nocase
condition:
all of them
}
Sigma Rule
title: CVE-2025-64753 - Unauthorized Access to Grist-core /compare Endpoint
id: 12345678-1234-1234-1234-123456789abc
status: experimental
description: Detects attempts to exploit CVE-2025-64753 by accessing the /compare endpoint with partial read access.
author: Valters IT
date: 2025-04-10
references:
- https://nvd.nist.gov/vuln/detail/CVE-2025-64753
logsource:
category: webserver
product: apache
service: access_log
detection:
selection:
cs-method: 'GET'
cs-uri-stem|contains: '/compare'
cs-uri-query|contains: 'from='
condition: selection
falsepositives:
- Legitimate use by users with full read access
level: medium
tags:
- attack.t1213
- cve.2025.64753
Suricata Rule
alert http any any -> any any (msg:"CVE-2025-64753 - Grist-core /compare Endpoint Access"; flow:to_server; content:"GET"; http_method; content:"/compare"; http_uri; content:"from="; http_uri; classtype:attempted-recon; sid:1000001; rev:1;)
Remediation & Mitigation
Immediate:
- Upgrade Grist-core to version 1.7.7 or later.
- If upgrade is not possible, block access to the
/compareendpoint at the web server or firewall level. - Remove sensitive document history using the
/states/removeendpoint.
Long-term:
- Implement proper access control checks for all endpoints that expose document history.
- Conduct a security audit of all API endpoints to ensure they enforce the principle of least privilege.
- Monitor for any unusual access patterns to version history endpoints.
Workaround:
- Block the
/compareendpoint via reverse proxy configuration (e.g., Nginx):location ~ ^/api/docs/[^/]+/compare { deny all; }
Valters IT
DevSecOps & Cyber Threat Intelligence