
Docker lab demonstrating CVE-2026-17532, an unauthenticated reflected XSS in Seraphinite Accelerator that chains to RCE via admin session, with exploit script and web shell.
A Docker lab for CVE-2026-17532, an unauthenticated reflected XSS in the WordPress plugin Seraphinite Accelerator that chains into remote code execution the moment a logged-in administrator opens one crafted link.
Full writeup: BLOG
python3 or php on the host (only to build the exploit URL - exploit.sh uses whichever is present)docker compose down -v # clean any old data
docker compose up -d
docker compose logs -f wpcli
Wait for LAB READY, then press Ctrl-C. WordPress is now at with the vulnerable plugin active and page caching enabled.
http://127.0.0.1:8080The wpcli container is a one-shot installer; it exits after setup. That is normal.
Log in as admin at http://127.0.0.1:8080/wp-admin
adminadmin-lab-pwBuild the crafted URL and open it in the same browser:
./exploit.sh # or: ./exploit.sh http://127.0.0.1:8080
The page hangs for ~5 seconds - that is a literal sleep( 5 ) in the plugin's selfTest branch, not a broken lab. Then the XSS runs, writes the web shell using your admin session, and logs the shell URL to the browser console.
http://127.0.0.1:8080/wp-content/plugins/hello.php?c=id
Or open it without ?c= for an interactive input box.
xss.js runs in the admin's session and same origin, so it can:
GET wp-admin/plugin-editor.php and scrape the one-time editor nonce out of the HTML.POST to admin-ajax.php with action=edit-theme-plugin-file, writing a PHP web shell into hello.php.Why hello.php? Because it is inactive. When you edit an active plugin and the change would fatal the site, WordPress detects the error and reverts the file. Inactive plugins skip that check, so the shell gets written and stays written. Any writable inactive plugin file works; hello.php just ships with WordPress by default.
The whole script is inlined into the crafted URL, so no attacker server is needed.
docker compose down -v