A high-severity stored cross-site scripting (Stored XSS) vulnerability in Mozilla Pontoon—the primary localization management platform powering translations for Firefox, Thunderbird, and mozilla.org—enabled unauthenticated attackers to execute arbitrary JavaScript within the active browser sessions of translation reviewers and platform administrators. Documented in coordinated public disclosure via HackerOne (Report #3988961) by security researcher timhaines, the flaw stems from client-side DOM re-parsing in dashboard tooltips, compounded by an accidental Content-Security-Policy (CSP) regression during a framework upgrade.
| Specification Parameter | Vulnerability Detail & Telemetry | Technical Risk & Exploit Impact |
|---|---|---|
| Target Platform | Mozilla Pontoon Localization Platform (pontoon.mozilla.org / pontoon.allizom.org) |
Web-based collaborative translation suite managing global release strings for Mozilla products. |
| Vulnerability Identifier | MOZILLA-2026-PONTOON-XSS / CWE-79 (Stored Cross-Site Scripting) |
Client-side DOM HTML re-parsing sink via jQuery .after() manipulation. |
| Severity Rating | High (CVSS 8.2) — CVSS:3.1/AV:N/AC:L/PR:N/UI:R/S:C/C:H/I:H/A:N |
Administrative session hijacking, unauthorized locale manager additions, and translation poisoning. |
| Vulnerable Sinks | Public Project Dashboards & Latest-Activity Tooltip Generator | Unchecked attribute decoding when generating contributor hover popups. |
| Reporter Attribution | Security Researcher timhaines |
Triaged by Mozilla Security and resolved in release v2026.10.08. |
The Pontoon Localization Ecosystem Architecture
Mozilla Pontoon coordinates the global volunteer and professional translation efforts that deliver Mozilla software in hundreds of languages. Through Pontoon's public web dashboards, contributors submit translation suggestions for UI strings, while designated Locale Managers and Translators review, approve, and merge strings into production version control repositories.
To foster community engagement and monitor translation velocity, Pontoon features public dashboards displaying project completion percentages, contributor leaderboards, and recent activity streams. When a user navigates to a dashboard, a client-side tooltip library generates interactive popups whenever the mouse hovers over an activity cell, displaying details about the contributor, timestamp, and submitted string.
Root Cause: The Client-Side HTML Re-Parsing Sink
The vulnerability stemmed from a subtle interaction between HTML entity encoding on the server and dynamic DOM manipulation in client-side JavaScript.
When the server rendered the dashboard HTML table, it output contributor information into HTML5 data-* attributes. The server properly HTML-encoded user input into these attributes:
<!-- Server-rendered activity cell -->
<td class="latest-activity"
data-author=""<script>alert(document.domain)</script>x"@example.org"
data-date="Oct 12, 2026">
</td>
However, when the client-side JavaScript script initialized the tooltip on hover, it constructed the popup markup by extracting the data-* values and concatenating them into an HTML string, which was subsequently passed to jQuery's .after() method:
// Vulnerable client-side tooltip construction logic:
var author = $cell.data('author'); // Browser automatically decodes HTML entities!
var date = $cell.data('date');
// VULNERABLE: Direct string interpolation into jQuery DOM injection sink!
var tooltipHtml = '<div class="tooltip">' +
'<span class="author">' + author + '</span>' +
'<span class="date">' + date + '</span>' +
'</div>';
$cell.after(tooltipHtml); // Executes unescaped script tags in the DOM!
Because the browser automatically decodes HTML entities when populating the element's dataset property, $cell.data('author') returned raw unescaped characters: "<script>alert(document.domain)</script>x"@example.org. When jQuery evaluated .after(tooltipHtml), it parsed the string as raw HTML, injecting active executable script elements directly into the live document object model!
The Exploitation Chain: RFC-Quoted Emails & CSP Regression
To deliver the payload without triggering backend email format rejections, researcher timhaines leveraged RFC 5322 section 3.4.1, which permits arbitrary characters—including angle brackets and quotes—inside the quoted local part of an email address:
"<script>alert(document.domain)</script>x"@example.org
When an attacker registered an account using this address and omitted an optional display name, Pontoon's user profile renderer defaulted to displaying their account email address as their contributor identifier. Submitting a single trivial translation suggestion placed the malicious script directly into the public activity stream on the project dashboard.
The Compounding Factor: Accidental CSP Regression
Modern applications rely on Content-Security-Policy (CSP) headers to neutralize XSS vulnerabilities by disallowing inline script execution. However, during an infrastructure upgrade to django-csp 4.0 immediately preceding the discovery, a configuration mismatch caused the staging environment (pontoon.allizom.org) to drop all CSP response headers. Consequently, the injected inline script fired without browser restriction the moment an administrator hovered over the activity cell!
Threat Modeling: Unauthorized Locale Hijacking & Release Poisoning
The execution of attacker-controlled JavaScript inside authenticated reviewer sessions created immediate administrative escalation vectors:
| Target Session Type | Adversary Action Executed via XSS | Operational Security Consequence |
|---|---|---|
| Translator Session | Silent background AJAX request to approve attacker's pending translation suggestions. | Adversary poisons localization strings in Firefox or Thunderbird language packs. |
| Locale Manager Session | Dispatches administrative request to add attacker's account to the locale managers group. | Permanent privilege escalation that survives session expiration and browser restarts. |
| Platform Administrator | Steals anti-CSRF tokens and triggers administrative API calls across the platform. | Complete administrative takeover of Pontoon infrastructure. |
Remediation & Upstream Pull Request Architecture
Mozilla resolved the vulnerability through three synchronized pull requests:
| Pull Request | Date Merged | Engineering Remediation Action |
|---|---|---|
| PR #4482 | September 2, 2026 | Removed vulnerable local email signup routes, requiring authenticated SSO via Mozilla accounts. |
| PR #4493 | September 3, 2026 | Restored and hardened strict Content-Security-Policy headers across all environments. |
| PR #4583 | October 8, 2026 | Completely eliminated the HTML sink, rebuilding tooltips using safe DOM text nodes. Released in v2026.10.08. |
Developers constructing dynamic web interfaces must avoid concatenating user-controlled data into HTML strings. Always construct DOM elements programmatically using safe APIs like document.createElement() and element.textContent:
// Safe programmatic DOM construction:
var $tooltip = $('<div class="tooltip"></div>');
var $authorSpan = $('<span class="author"></span>').text($cell.data('author'));
var $dateSpan = $('<span class="date"></span>').text($cell.data('date'));
$tooltip.append($authorSpan).append($dateSpan);
$cell.after($tooltip);



