Executive Summary
A critical stored cross-site scripting (XSS) vulnerability (CVE-2026-40470) has been disclosed in hackage-server, the software powering hackage.haskell.org — the central package repository for the Haskell programming language ecosystem. The flaw carries a CVSS score of 9.9 and represents a significant supply chain risk given Hackage's role as the primary distribution channel for Haskell libraries.
The vulnerability stems from HTML and JavaScript files included in source packages or uploaded via the documentation upload facility being served as raw content on the hackage.haskell.org domain — without sanitization or content-type enforcement. When an authenticated Hackage user visits a page containing such content, the attacker-controlled script executes in their browser with access to their Hackage session credentials, enabling account takeover and potential supply chain compromise.
The issue has been patched on the live hackage.haskell.org service. Operators of self-hosted hackage-server instances must update immediately.
Vulnerability Overview
| Attribute | Value |
|---|---|
| CVE ID | CVE-2026-40470 |
| CVSS Score | 9.9 (Critical) |
| CWE | CWE-79 — Cross-Site Scripting (Stored) |
| Type | Stored XSS / Account Takeover / Supply Chain Risk |
| Attack Vector | Network |
| Privileges Required | Low (package upload access) |
| User Interaction | Required (victim browses to malicious package page) |
| Scope | Changed |
| Confidentiality Impact | High |
| Integrity Impact | High |
| Availability Impact | High |
| Patch Available | Yes — patched on hackage.haskell.org |
Affected Versions
| Component | Affected Versions | Status |
|---|---|---|
| hackage.haskell.org | Prior to patch deployment | Patched |
| hackage-server (self-hosted) | All versions prior to fix | Update required |
Technical Analysis
Root Cause
The hackage-server software serves files from uploaded Haskell source packages and documentation archives directly to requesting browsers. Prior to the fix, the server failed to enforce proper content-type headers or apply sanitization when serving HTML (.html) and JavaScript (.js) files included in:
- Source packages uploaded by package maintainers
- Documentation archives submitted via the documentation upload facility
When these files are served under the hackage.haskell.org domain without content-type override (e.g., Content-Type: text/plain or X-Content-Type-Options: nosniff), browsers interpret them as active HTML/JavaScript and execute any embedded scripts in the context of the hackage.haskell.org origin.
Because all authenticated Hackage users share this origin, a script running under it can:
- Access the user's session cookies (if not
HttpOnly) - Read and exfiltrate CSRF tokens
- Perform authenticated actions on behalf of the victim (upload, modify, delete packages)
- Modify package metadata or inject malicious content
Attack Scenario
1. Attacker creates a Hackage account and uploads a package
2. Package's source archive includes a crafted .html or .js file with a malicious payload
3. Hackage serves the file under hackage.haskell.org domain as active HTML
4. Attacker distributes a link to the file — e.g., in a bug report, forum post, or email
5. Authenticated Hackage maintainer or admin visits the link
6. Browser executes the script in the context of hackage.haskell.org
7. Script exfiltrates session credentials or performs privileged actions
8. Attacker gains control of victim's Hackage account
9. Attacker can publish trojanized versions of packages owned by the victimSupply Chain Implications
Control of a popular Hackage package maintainer's account enables:
- Uploading malicious package revisions that inject backdoors into Haskell libraries
- Modifying package metadata to redirect users to attacker-controlled repositories
- Hijacking widely-used packages affecting downstream Haskell projects worldwide
- Compromising Haskell CI/CD pipelines that consume packages from Hackage
The CVSS score of 9.9 reflects the cascading supply chain risk beyond direct credential theft.
Impact Assessment
| Impact Area | Description |
|---|---|
| Account Takeover | Session hijacking via XSS payload targeting authenticated maintainers |
| Package Hijacking | Attacker gains upload access to packages owned by victim |
| Supply Chain Poisoning | Malicious code injected into widely-used Haskell libraries |
| CI/CD Compromise | Downstream build pipelines automatically pull poisoned package versions |
| CSRF Token Theft | Cross-site request forgery combined with XSS amplifies attack surface |
| Reputation Damage | Trust in Hackage as a safe repository is undermined |
Immediate Remediation
For hackage.haskell.org Users
The vulnerability has been patched on the official hackage.haskell.org service. No action is required for standard users beyond:
# If you have package upload access, check your account for unauthorized activity
# Review package revision history for unexpected uploads
cabal info <package-name>Maintainers of popular packages should rotate Hackage credentials and review recent package upload history for unauthorized revisions.
For Self-Hosted hackage-server Operators
# Pull the latest hackage-server from Hackage or GitHub
cabal update
cabal install hackage-server
# Or via stack
stack upgrade hackage-server
# Verify version and apply content-type configuration fixes
hackage-server --versionApply the following server hardening regardless of version:
# Nginx — force text/plain for package file serving, block HTML execution
location ~* \.(html|js|htm)$ {
add_header Content-Type "text/plain" always;
add_header X-Content-Type-Options "nosniff" always;
}Rotate Hackage Credentials
If you are a Hackage package maintainer:
- Navigate to your Hackage account settings and change your password
- Review your packages' recent revision history for unauthorized uploads
- If a CSRF token may have been stolen, invalidate active sessions
- Enable two-factor authentication if supported by your Hackage instance
Detection Indicators
| Indicator | Description |
|---|---|
| Package revisions uploaded at unexpected times | Potential post-account-takeover upload |
| Login events from unfamiliar IPs or user agents | Hijacked session in use |
| HTML/JS files in package source archives | Potential exploit payload staged for delivery |
| Unusual CSRF errors or session invalidation events | XSS payload interaction with server |
| New maintainer accounts added to packages | Attacker establishing persistent access |
Post-Remediation Checklist
- Update self-hosted hackage-server instances to the patched version immediately
- Add
Content-Type: text/plainandX-Content-Type-Options: nosniffheaders for all package file serving - Rotate Hackage account credentials, particularly for active package maintainers
- Audit recent package revision history for unauthorized uploads
- Review maintainer lists for packages to detect unauthorized access grants
- Enable 2FA on all maintainer accounts where available
- Notify downstream consumers if packages were potentially compromised
- Monitor repository access logs for continued suspicious activity