Skip to main content
CVE Vulnerability Database
Vulnerability Database/CVE-2026-55665

CVE-2026-55665: Grist Spreadsheet XSS Vulnerability

CVE-2026-55665 is a cross-site scripting flaw in Grist spreadsheet software that allows attackers to execute malicious scripts in victims' sessions. This article covers the technical details, affected versions, and mitigation.

Published:

CVE-2026-55665 Overview

CVE-2026-55665 identifies two cross-site scripting (XSS) vulnerabilities in Grist, a spreadsheet application that uses Python as its formula language. Both flaws allowed attacker-controlled values to reach a link's href attribute without scheme validation. An attacker could store a javascript: URL that executed in a victim's authenticated Grist origin on a single click. The affected code paths are /welcome/select-account (using the next query parameter) and document tours (using the Link_URL column in the GristDocTour table). The vulnerability is fixed in Grist version 1.7.15.

Critical Impact

A document editor could escalate to owner-level access by executing arbitrary JavaScript in another user's session, calling Grist APIs to read or modify data and change sharing settings.

Affected Products

  • Grist (grist-core) versions prior to 1.7.15
  • Grist self-hosted deployments serving the /welcome/select-account endpoint
  • Grist documents shared with editor-level collaborators using document tours

Discovery Timeline

  • 2026-07-10 - CVE-2026-55665 published to NVD
  • 2026-07-14 - Last updated in NVD database

Technical Details for CVE-2026-55665

Vulnerability Analysis

Both issues are classic DOM-based cross-site scripting flaws categorized under [CWE-79]. The Grist client rendered untrusted string values directly into <a> tag href attributes without validating the URL scheme. Browsers treat javascript: URLs in href attributes as executable code when the link is activated, which allowed attacker-supplied payloads to run under the victim's origin.

Because the payload executes inside an authenticated session, the JavaScript inherits the victim's cookies and CSRF tokens. It can invoke any Grist API the victim is authorized to use, including endpoints that modify access control lists. An attacker with editor rights on a shared document can therefore escalate to owner-level access on that document.

Root Cause

The root cause is missing URL sanitization in two client-side TypeScript modules. The WelcomePage.ts file rendered the next query parameter into account-selection buttons, and DocTour.ts rendered the Link_URL column value from the GristDocTour metadata table into tour link buttons. Neither call site invoked the existing sanitizeUrl helpers before assigning the value to href.

Attack Vector

Exploitation requires a single user interaction: the victim must click the malicious button or tour link. For the welcome-page vector, an attacker crafts a URL such as /welcome/select-account?next=javascript:... and induces the victim to visit and click. For the document-tour vector, an editor stores a javascript: URL in the GristDocTourLink_URL column, and any user opening the document and clicking the tour link triggers execution.

typescript
// Patch: app/client/ui/DocTour.ts
 import { DocComm } from "app/client/components/DocComm";
 import { makeT } from "app/client/lib/localization";
+import { sanitizeLinkUrl } from "app/client/lib/sanitizeUrl";
 import { sameDocumentUrlState } from "app/client/models/gristUrlState";
 import { cssButtons, cssLinkBtn, cssLinkIcon } from "app/client/ui/ExampleCard";
 import { IOnBoardingMsg, startOnBoarding } from "app/client/ui/OnBoardingPopups";

// Patch: app/client/ui/WelcomePage.ts
 import { handleSubmit } from "app/client/lib/formUtils";
+import { sanitizeHttpUrl } from "app/client/lib/sanitizeUrl";
 import { getLoginUrl, getSignupUrl } from "app/client/lib/urlUtils";
 import { AppModel } from "app/client/models/AppModel";
 import { urlState } from "app/client/models/gristUrlState";
// Source: https://github.com/gristlabs/grist-core/commit/5d0a90a162b5125fce7e8a86fb137eee5199dbde

The fix imports sanitizeLinkUrl and sanitizeHttpUrl and applies them to the untrusted values before they reach the href attribute, rejecting any scheme outside the allowed HTTP/HTTPS set.

Detection Methods for CVE-2026-55665

Indicators of Compromise

  • Values beginning with javascript:, data:, or vbscript: stored in the Link_URL column of any GristDocTour table.
  • HTTP request logs containing /welcome/select-account?next=javascript: or URL-encoded equivalents such as next=javascript%3A.
  • Unexpected changes to document sharing settings or access rules performed by non-owner accounts through the Grist API.
  • Grist API calls originating from browser sessions immediately following a click on a tour link or account-selection button.

Detection Strategies

  • Query the GristDocTour metadata table across all documents and flag rows where Link_URL does not start with http:// or https://.
  • Parse web-server access logs for the next query parameter and alert on non-HTTP schemes.
  • Correlate access-rule and sharing-setting change events with the acting user's role at the time of change to identify editor-to-owner escalations.

Monitoring Recommendations

  • Enable audit logging for Grist access-rule modifications and sharing-permission changes.
  • Monitor the Grist installation's version banner and confirm it reports 1.7.15 or later after patching.
  • Review browser Content Security Policy (CSP) violation reports for script-src inline execution attempts on Grist origins.

How to Mitigate CVE-2026-55665

Immediate Actions Required

  • Upgrade all Grist instances to version 1.7.15 or later, which is available from the GitHub Release v1.7.15.
  • Audit every shared document for suspicious Link_URL entries in GristDocTour tables and remove non-HTTP values.
  • Review recent access-rule and sharing-permission changes on shared documents and revert unauthorized modifications.
  • Rotate API keys for accounts that may have been targeted while an unpatched instance was in use.

Patch Information

The vendor released the fix in Grist 1.7.15. The remediation adds calls to sanitizeHttpUrl in WelcomePage.ts and sanitizeLinkUrl in DocTour.ts so that only HTTP and HTTPS schemes are permitted in the affected href targets. Full technical details are available in the GitHub Security Advisory GHSA-7f6v-vghq-34xq and the GitHub Commit Details.

Workarounds

  • If immediate patching is not possible, temporarily downgrade editor permissions on shared documents to prevent modification of GristDocTour tables.
  • Deploy a reverse-proxy rule that blocks requests to /welcome/select-account when the next query parameter contains a non-HTTP scheme.
  • Apply a strict Content Security Policy that forbids inline JavaScript execution on the Grist origin.
bash
# Example nginx rule blocking non-HTTP next= parameters
location /welcome/select-account {
    if ($arg_next ~* "^(?!https?:)") {
        return 400;
    }
    proxy_pass http://grist_upstream;
}

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Default Legacy - Prefooter | Experience the World’s Most Advanced Cybersecurity Platform

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.