CVE-2026-21618 Overview
CVE-2026-21618 is a Cross-Site Scripting (XSS) vulnerability discovered in hexpm, the package manager repository for the Elixir and Erlang ecosystems. The vulnerability exists in the HexpmWeb.SharedAuthorizationView module, specifically within the render_grouped_scopes/3 function located in lib/hexpm_web/views/shared_authorization_view.ex. This flaw allows attackers to inject malicious scripts through improperly neutralized user input during web page generation, potentially compromising user sessions and sensitive data.
Critical Impact
Attackers can execute arbitrary JavaScript in the context of authenticated hex.pm users, potentially stealing session tokens, API keys, or performing unauthorized actions on behalf of victims.
Affected Products
- hexpm from commit 617e44c71f1dd9043870205f371d375c5c4d886d before commit c692438684ead90c3bcbfb9ccf4e63c768c668a8
- hex.pm platform from 2025-10-01 before 2026-01-19
Discovery Timeline
- 2026-01-19 - CVE CVE-2026-21618 published to NVD
- 2026-01-19 - Last updated in NVD database
Technical Details for CVE-2026-21618
Vulnerability Analysis
The vulnerability resides in how hexpm handles user-agent strings when rendering dashboard views. The affected code uses Phoenix.HTML.html_escape/1 for escaping user input that is subsequently embedded within HTML data attributes. However, when this escaped content is rendered within popover elements that interpret the content as HTML, a double-encoding issue creates an XSS vector. The user-agent string, which is attacker-controlled, was not being properly escaped for the context in which it was being rendered, allowing malicious payloads to execute when users interact with dashboard elements displaying session or API key information.
Root Cause
The root cause is insufficient output encoding for context-specific rendering. The original implementation used Phoenix.HTML.html_escape/1 to escape user-agent strings before embedding them in data-content attributes. However, these attributes are processed by Bootstrap popovers which render the content as HTML. This means the single escape was decoded by the popover renderer, allowing any XSS payload within the user-agent to execute. The fix introduces a double_html_escape/1 function that applies HTML escaping twice, ensuring the content remains safe even after the popover's HTML rendering pass.
Attack Vector
An attacker can exploit this vulnerability by crafting a malicious user-agent string containing JavaScript payloads when making API requests to hex.pm. When an authenticated user views their dashboard (specifically the API keys or sessions pages) and interacts with elements showing "last use" information, the malicious script executes in their browser context. The attack requires user interaction (clicking on the popover element) but can be facilitated through social engineering.
// Security patch in lib/hexpm_web/templates/dashboard/_keys.html.eex
data-trigger="focus"
data-placement="bottom"
title="Last use"
- data-content="<strong>Used at:</strong> <%= ViewHelpers.pretty_datetime(last_use.used_at) %><br><strong>IP:</strong> <%= last_use.ip %><br><strong>User agent:</strong> <%= Phoenix.HTML.html_escape(last_use.user_agent) %>">
+ data-content="<strong>Used at:</strong> <%= ViewHelpers.pretty_datetime(last_use.used_at) %><br><strong>IP:</strong> <%= last_use.ip %><br><strong>User agent:</strong> <%= double_html_escape(last_use.user_agent) %>">
<%= ViewHelpers.pretty_date(last_use.used_at) %> ...
</a>
<% end %>
Source: GitHub Commit c692438
Detection Methods for CVE-2026-21618
Indicators of Compromise
- Unusual user-agent strings in access logs containing HTML/JavaScript syntax such as <script>, onerror=, or javascript: sequences
- API key or session usage from unexpected IP addresses or with anomalous user-agent patterns
- Reports from users of unexpected browser behavior when viewing their hex.pm dashboard
Detection Strategies
- Implement Web Application Firewall (WAF) rules to detect and block requests with user-agent strings containing common XSS payloads
- Monitor application logs for user-agent strings exceeding normal length or containing encoded characters typical of XSS attempts
- Deploy Content Security Policy (CSP) headers to limit the impact of successful XSS exploitation
Monitoring Recommendations
- Enable detailed logging for all API authentication events, including full user-agent strings
- Set up alerts for user-agent strings matching XSS payload patterns
- Monitor for session token reuse from different IP addresses, which may indicate session theft
How to Mitigate CVE-2026-21618
Immediate Actions Required
- Update hexpm to commit c692438684ead90c3bcbfb9ccf4e63c768c668a8 or later immediately
- Review API key and session activity for any suspicious patterns
- Consider rotating API keys if unusual activity is detected
- Implement CSP headers as an additional defense layer
Patch Information
The vulnerability has been patched in commit c692438684ead90c3bcbfb9ccf4e63c768c668a8. The fix introduces a double_html_escape/1 helper function in DashboardView that properly escapes user-controlled input for contexts where content is rendered as HTML within Bootstrap popovers. For detailed patch information, refer to the GitHub Security Advisory GHSA-6cw9-5gg4-rhpj and the commit change log.
Workarounds
- If immediate patching is not possible, consider disabling the popover functionality that displays user-agent information
- Implement strict Content Security Policy headers to prevent inline script execution
- Use a reverse proxy or WAF to sanitize or reject requests with suspicious user-agent strings
# Example CSP header configuration for nginx
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; object-src 'none';" always;
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

