Frappe Framework 17.0.0-dev - Stored XSS in Notifications Events color rendering

4.8

Medium

Detected by

Fluid Attacks AI SAST Scanner

Disclosed by

Oscar Uribe

Summary

Full name

Frappe Framework 17.0.0-dev - Stored XSS in Notifications Events color rendering

Code name

State

Public

Release date

Affected product

Frappe Framework

Vendor

Frappe

Affected version(s)

17.0.0-dev

Vulnerability name

Stored cross-site scripting (XSS)

Remotely exploitable

Yes

CVSS v4.0 vector string

CVSS:4.0/AV:N/AC:L/AT:N/PR:L/UI:A/VC:N/VI:N/VA:N/SC:L/SI:L/SA:N

CVSS v4.0 base score

4.8

Exploit available

Yes

Description

A Stored Cross-Site Scripting (XSS) vulnerability exists in Frappe Framework version 17.0.0-dev due to improper neutralization of user-controlled input in the Notifications > Events panel. Event data returned from the server is interpolated into an HTML template string and rendered using jQuery's .html() method without adequate escaping or sanitization.

The vulnerability arises because the Event.color field is inserted directly into an inline style attribute. An attacker with permission to create or modify Event records can store a crafted payload that breaks out of the attribute context and injects arbitrary HTML attributes, such as JavaScript event handlers. When another user opens the Events notifications panel and interacts with the affected entry, attacker-controlled code may execute in the victim's browser.

Vulnerability

Case A: Event.color attribute injection in notifications dropdown

  1. Source persistence: attacker-controlled Event.color is stored in database.

  2. Server propagation: frappe.desk.doctype.event.event.get_events returns color using SQL as_dict=True.

  3. Client interpolation: EventsView.render_events_html injects it in:

    • <div class="event-border" style="border-color: ${event.color}"></div>

  4. Sink: rendered string is inserted with this.container.html(html).

  5. Impact: quote-breaking payload injects event-handler attributes and executes in victim Desk session.

Case B: non-primary claims

  • subject is not the validated vector here. Runtime tests showed dangerous handlers are removed on save by document sanitization.

  • name is not attacker-controlled in normal Event flow (EV.##### autoname).

  • avatar_group path is not active in this function because the code reads event.particpants (typo) and participants are not returned in the current query.

Relevant code:

  • frappe/frappe/public/js/frappe/ui/notifications/notifications.js:422-489

  • frappe/frappe/desk/doctype/event/event.py:335-417

  • frappe/frappe/desk/doctype/event/event.json:373-383

  • frappe/frappe/model/base_document.py:1356-1396

PoC

GUI flow

  1. Login to Desk as a user that can create/edit Event (default Desk User can write).

  2. Create a Public event scheduled for today with status Open.

  3. Set Color to payload:

red; width: 120px; height: 28px; background: yellow; display:block" data-evxss="1" onmouseenter="alert(document.domain)
red; width: 120px; height: 28px; background: yellow; display:block" data-evxss="1" onmouseenter="alert(document.domain)
red; width: 120px; height: 28px; background: yellow; display:block" data-evxss="1" onmouseenter="alert(document.domain)
red; width: 120px; height: 28px; background: yellow; display:block" data-evxss="1" onmouseenter="alert(document.domain)
  1. Save event.

  2. Open http://localhost:18080/desk.

  3. Open notifications (bell icon) and go to Events tab.

  4. Hover the event's left color bar (.event-border).

Expected result:

  • JavaScript executes (alert(document.domain)).

API check (optional)

Verify payload reaches source API unchanged for the current day:

http://localhost:18080/api/method/frappe.desk.doctype.event.event.get_events?start=2026-03-12&end=2026-03-12
http://localhost:18080/api/method/frappe.desk.doctype.event.event.get_events?start=2026-03-12&end=2026-03-12
http://localhost:18080/api/method/frappe.desk.doctype.event.event.get_events?start=2026-03-12&end=2026-03-12
http://localhost:18080/api/method/frappe.desk.doctype.event.event.get_events?start=2026-03-12&end=2026-03-12

Evidence of Exploitation

  • Video of exploitation

Our security policy

We have reserved the ID CVE-2026-50709 to refer to this issue from now on.

System Information

  • Frappe Framework

  • Version 17.0.0-dev

  • Operating System: Any

References

Mitigation

There is currently no patch available for this vulnerability.

Credits

The vulnerability was discovered by Oscar Uribe from Fluid Attacks' Offensive Team using the AI SAST Scanner.

Timeline

Vulnerability discovered

Vendor contacted

Vendor replied

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.