## https://sploitus.com/exploit?id=1E156C2F-E7B6-53C8-81B6-2C04BF288661
# CVE-2026-64638 - WordPress `wp-login.php` Reflected XSS ("XSS2Shell")
Reflected XSS in WordPress Core, CVSS 8.9 (v4.0), CWE-79.
- NVD:
- GitHub Security Advisory:
- Official fix announcement:
**Affected:** WordPress Core 4.7.0 through 7.0.2 (every branch that was
still receiving security fixes). WordPress 4.6 and earlier are end-of-life
and were never patched β they remain vulnerable indefinitely.
**Fixed in:** 7.0.3 on trunk, backported to each maintained branch.
Confirmed point releases: 7.0.3, 6.9.6, 6.8.7. WordPress backports security
fixes to every branch it still supports, so other branches almost certainly
have a fixed point release too β this repo just doesn't have every exact
number confirmed, so it never guesses one (see `version_is_patched()` in
the script).
## Usage
```bash
# Companion scanner template (only if you already run that scanner elsewhere)
python3 cli.py --target https://example.com --template CVE-2026-64638.yaml
# Standalone script β the only prerequisite is Python 3.9+, stdlib only
python3 cve-2026-64638-poc.py check https://example.com
python3 cve-2026-64638-poc.py audit https://example.com
python3 cve-2026-64638-poc.py trigger --target example.com > demo.html
```
Both `check` and `audit` open with an interactive authorization prompt
before sending any request β pass `--yes` to skip it for scripted/CI use.
Useful controls on both:
| Flag | Purpose |
|---------------|------------------------------------------------------------------|
| `--timeout` | per-request timeout in seconds (default: 10) |
| `--retries` | attempts per request on a transport-level failure only β a real HTTP response (even 4xx/5xx) is never retried (default: 2) |
| `--delay` | minimum seconds between requests to the target (default: 0) |
| `--yes` | skip the interactive authorization prompt |
| `--no-color` | disable ANSI colored output (also respects the `NO_COLOR` env var and auto-disables when stdout isn't a terminal) |
| `--json` | emit a single machine-readable JSON object instead of the human report |
`check` exits `0` when the reflection is confirmed, `1` when it isn't, `2`
when the target was unreachable (never conflated with "not vulnerable"),
and `3` when authorization was declined.
`audit` prints a weighted risk report (grade AβF) covering version exposure,
the reflection itself, common sensitive-file exposure, security headers, and
REST API user enumeration, and returns the numeric risk score as its exit
code (`--json` returns the same data as structured output).
The version line in both commands is corroboration only; it can read "unknown" for a branch this repo has no confirmed
patched point-release for. The reflection probe is always the ground truth.
## Testing
```bash
python3 cve-2026-64638-tests.py
# or
python3 -m pytest cve-2026-64638-tests.py
```
All 30 tests run against mocked HTTP responses.
## Scope / authorization
Authorized security testing only. Use exclusively against hosts you own or
have explicit written permission to test. Both `check` and `audit` refuse to
run in a non-interactive session unless `--yes` is passed to
prevent an unattended script from firing at an unauthorized target by
accident. Nothing in this folder automates the downstream session-hijack/RCE
stages of the wider chain; it stops at confirming the reflected-XSS entry
point and reporting on it.
## Remediation
Upgrade WordPress Core to 7.0.3 or later, or the equivalent backported point
release for your branch (e.g. 6.9.6, 6.8.7). Sites on 4.6 or earlier have no
available fix and should be upgraded off that branch entirely.