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

CVE-2026-69075: FlowIntel Stored XSS Vulnerability

CVE-2026-69075 is a stored XSS vulnerability in FlowIntel that allows attackers to inject Vue expressions through user-controlled fields. This post explains its impact, affected versions, and mitigation steps.

Published:

CVE-2026-69075 Overview

CVE-2026-69075 is a stored cross-site scripting (XSS) vulnerability in FlowIntel, a threat intelligence and case management platform. The flaw exists because persisted values across multiple user- and administrator-controlled fields are rendered inside DOM elements that Vue.js subsequently compiles. Standard HTML escaping neutralizes direct HTML markup but does not break Vue interpolation expressions using the application's configured [[ ... ]] delimiters. An authenticated attacker can persist a malicious Vue expression that executes when other users view the affected content.

Critical Impact

Successful exploitation allows arbitrary JavaScript execution in the victim's browser under the FlowIntel origin, exposing session data and permitting actions performed with the victim's privileges.

Affected Products

  • FlowIntel case management application (pre-patch commit b0e99aa)
  • FlowIntel components rendering case titles, ticket identifiers, and recurring-case information
  • FlowIntel account, organisation, role, configuration, and navigation views

Discovery Timeline

  • 2026-08-03 - CVE-2026-69075 published to NVD
  • 2026-08-03 - Last updated in NVD database

Technical Details for CVE-2026-69075

Vulnerability Analysis

The vulnerability is a stored XSS classified under [CWE-79]. FlowIntel uses Vue.js with custom interpolation delimiters ([[ ... ]]) rather than the default {{ }}. Server-side templates emit persisted database values into the DOM using Jinja auto-escaping, which converts characters such as <, >, and & into HTML entities. However, Jinja escaping leaves the [ and ] characters intact.

When Vue mounts and compiles the resulting DOM subtree, it parses any [[ expression ]] sequences as JavaScript interpolation expressions. This transforms client-side template rendering into an injection sink even though the initial server-rendered HTML looks safe. The attack qualifies as persistent because the payload is stored in the FlowIntel database and re-served to every subsequent viewer.

Root Cause

The root cause is a mismatch between server-side output encoding and the Vue client-side template compilation layer. Fields including case titles, ticket identifiers, recurring-case information, user profile attributes, organisation names, and role names were rendered without escaping the Vue-specific delimiter characters. See the GitHub Commit on FlowIntel for the exact fields affected.

Attack Vector

An authenticated attacker with permission to modify one of the affected fields stores a Vue interpolation payload such as [[ constructor.constructor('alert(1)')() ]]. When a second user browses the affected case, report, profile, recurring-case page, or navigation component, Vue evaluates the expression in the context of the FlowIntel application. The attacker can exfiltrate session tokens, invoke privileged API endpoints on behalf of the victim, or modify records within the victim's authorization scope.

python
# Patch: introduces vue_escape filter in app/__init__.py
from flask_session import Session
from flask_login import LoginManager
from werkzeug.middleware.proxy_fix import ProxyFix
from markupsafe import Markup, escape

from conf.config import config as Config
import os

Source: GitHub Commit on FlowIntel

text
<!-- Patch applied to app/templates/account/account_index.html -->
<tr>
    <td style="color:#494950">First name</td>
-    <td>{{user.first_name}}</td>
+    <td>{{ user.first_name|vue_escape }}</td>
</tr>
<tr>
    <td style="color:#494950">Last name</td>
-    <td>{{user.last_name}}</td>
+    <td>{{ user.last_name|vue_escape }}</td>
</tr>
<tr>
    <td style="color:#494950">Email</td>
-    <td>{{user.email}}</td>
+    <td>{{ user.email|vue_escape }}</td>
</tr>

Source: GitHub Commit on FlowIntel

The patch registers a vue_escape Jinja filter that escapes HTML-sensitive characters and breaks the [[ and ]] interpolation delimiters before values reach the browser.

Detection Methods for CVE-2026-69075

Indicators of Compromise

  • Persisted field values containing the substrings [[ and ]] in FlowIntel case titles, ticket identifiers, recurring-case data, profile fields, organisation names, or role names.
  • Vue expression artifacts such as constructor.constructor, this.$root, or $http appearing in stored records.
  • Outbound HTTP requests from user browsers to attacker-controlled hosts originating from the FlowIntel application origin.
  • Unexpected API calls performed under legitimate user sessions immediately after a case, profile, or navigation view.

Detection Strategies

  • Query the FlowIntel database for records containing [[ in the fields listed in the patch and review historical audit logs for their creation.
  • Monitor web server logs for POST or PUT requests to case, account, organisation, and role endpoints containing bracket-delimited payloads.
  • Deploy a Content Security Policy report-only header and inspect violation reports for script or connect-src anomalies.

Monitoring Recommendations

  • Enable per-user audit logging for modifications to the affected FlowIntel entities and forward events to a central SIEM.
  • Baseline normal API call patterns per role and alert on deviations following a case or profile view.
  • Watch for browser-originated requests to unfamiliar external domains from authenticated FlowIntel sessions.

How to Mitigate CVE-2026-69075

Immediate Actions Required

  • Update FlowIntel to a build that includes commit b0e99aa6d2708730bc422ebb6dc0c14d732389fa which introduces the vue_escape filter.
  • Audit existing records in the affected fields and sanitize or delete any entries containing Vue interpolation delimiters.
  • Rotate session cookies and force re-authentication for all users if injected payloads are found in the database.
  • Review role assignments and remove modification privileges from accounts that do not require them.

Patch Information

The upstream fix is available in the FlowIntel repository as commit b0e99aa6d2708730bc422ebb6dc0c14d732389fa. The patch imports Markup and escape from markupsafe, defines a dedicated vue_escape Jinja filter, and applies the filter to all affected case, account, organisation, role, configuration, and navigation templates. See the GitHub Commit on FlowIntel for the full diff.

Workarounds

  • Apply the vue_escape filter manually to any additional templates that render database-sourced values before Vue compiles the DOM.
  • Deploy a strict Content Security Policy that forbids inline event handlers and restricts connect-src to trusted origins.
  • Temporarily restrict edit permissions on case titles, ticket identifiers, recurring-case fields, profile attributes, organisation names, and role names until patching completes.
bash
# Verify the FlowIntel deployment includes the vue_escape filter
cd /opt/flowintel
git log --oneline | grep b0e99aa
grep -r "vue_escape" app/templates/ | wc -l

# Search stored records for existing Vue interpolation payloads
psql -U flowintel -d flowintel -c \
  "SELECT id, title FROM cases WHERE title LIKE '%[[%' OR title LIKE '%]]%';"

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.