
Plane 1.3.1 - Stored XSS in intake issue description_html
6.9
Medium
Discovered by
Offensive Team, Fluid Attacks
Summary
Full name
Plane 1.3.1 - Stored XSS in intake issue description_html
Code name
State
Public
Release date
Affected product
Plane
Vendor
Plane
Affected version(s)
1.3.1
Remotely exploitable
Yes
CVSS v4.0 vector string
CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:P/VC:H/VI:N/VA:N/SC:L/SI:L/SA:N
CVSS v4.0 base score
6.9
Exploit available
Yes
CVE ID(s)
Description
Plane CE 1.3.1 allows a low-privileged project member to submit arbitrary HTML/JS in the description_html field when creating an intake work item through the API v1 intake endpoint.
The backend persists this HTML directly in the underlying Issue record without applying the existing server-side HTML sanitizer used by normal issue serializers. In the validated self-hosted Plane UI, the stored content is later loaded into the intake work item view, and attacker-controlled JavaScript executes in the browser session of a user who reviews the intake item.
Vulnerability
Case A (validated): Stored XSS via intake description_html
1. Source:
- API request body field issue.description_html.
- Endpoint: POST /api/v1/workspaces/{workspace_slug}/projects/{project_id}/intake-issues/.
2. Missing validation:
- The API v1 intake creation path creates an Issue directly and assigns description_html=issue_data.get("description_html", "<p></p>").
- This bypasses IssueSerializer.validate(), where validate_html_content() sanitizes HTML with nh3.
3. Sinks:
- The malicious HTML is persisted in Issue.description_html.
- The intake UI loads the persisted value as the initial description for the rich-text intake work item view.
4. Impact:
- A low-privileged project member, including a guest project member with an API token, can store active HTML in an intake work item.
- When a privileged user reviews the intake item, JavaScript can execute in that user's Plane session.
- This can expose data or actions available to the reviewing user.
Relevant code:
plane/apps/api/plane/api/views/intake.py:190
plane/apps/api/plane/api/views/intake.py:193
plane/apps/api/plane/api/views/intake.py:378
plane/apps/api/plane/space/views/intake.py:145
plane/apps/api/plane/space/views/intake.py:148
plane/apps/api/plane/api/serializers/issue.py:93
plane/apps/api/plane/api/serializers/issue.py:94
plane/apps/api/plane/utils/content_validator.py:224
plane/apps/api/plane/app/permissions/project.py:133
plane/apps/web/core/components/inbox/content/issue-root.tsx:178
PoC
Run Plane CE and create a workspace/project with Intake enabled. Create a low-privileged project user, generate an API token for that user, and submit an intake work item.
Expected backend result:
The response is 201 Created.
The returned issue detail contains the supplied description_html with the event handler still present.
Expected UI result in the validated self-hosted environment:
Log in as a workspace/project administrator.
Open the project's Intake view and select the submitted work item.
The stored payload executes in the administrator's browser context and displays an alert for document.domain.
Evidence of exploitation
Video of exploitation:
Static evidence:

Our security policy
We have reserved the ID CVE-2026-10850 to refer to this issue from now on.
System Information
Plane CE
Version: 1.3.1
Operating System: Any
References
Github Repository: https://github.com/makeplane/plane
Mitigation
There is currently no patch available for this vulnerability.
Credits
The vulnerability was discovered by Oscar Naveda from Fluid Attacks' Offensive Team.
Timeline
Vulnerability discovered
Vendor contacted
Public disclosure
Does your application use this vulnerable software?
During our free trial, our tools assess your application, identify vulnerabilities, and provide recommendations for their remediation.













