Vulnerable WordPress 6.9.0 Docker lab for testing CVE-2026-63030 (REST API Batch Route Confusion) and CVE-2026-60137 (Blind SQLi via author__not_in).
Two variants: a plain lab and one behind a Cloudflare-style ModSecurity WAF.
cd lab
docker compose up -d --buildWordPress 6.9.0 comes up on http://localhost:8888 (admin / Summer2026!). The setup script installs WordPress, publishes a post to use as the oEmbed anchor, sets FS_METHOD=direct for plugin uploads, and enables pretty permalinks so /wp-json/batch/v1 resolves. It is ready in about 10 seconds.
Check the logs for the ready banner:
docker compose logs -f wp[lab] wp2shell Lab Ready
[lab] WordPress 6.9.0 (VULNERABLE)
[lab] URL: http://localhost:8888
[lab] Admin: admin / Summer2026!
cd lab/waf
docker compose up -d --buildSame WordPress behind OWASP ModSecurity CRS on http://localhost:9999. The included rule set (REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf) disables CRS's JSON-decoding SQLi rules and re-adds equivalent rules that match the raw request body, mirroring how Cloudflare inspects traffic. A plaintext SLEEP( payload is blocked with a 403; the same payload with the SQL keywords JSON-unicode-escaped passes through.
lab/
├── docker-compose.yml # WordPress 6.9.0 + MariaDB 11.4 (port 8888)
├── Dockerfile
├── setup.sh
└── waf/
├── docker-compose.yml # adds ModSecurity in front (port 9999)
└── REQUEST-900-EXCLUSION-RULES-BEFORE-CRS.conf # Cloudflare-style raw-body rules
docker compose down -vWordPress 6.9.0 reports its version as 6.9 in the generator tag. The batch route returns 207 Multi-Status on the affected versions. Fixed in 6.8.6, 6.9.5, and 7.0.2 — use one of those to confirm a target is patched.
For authorized security testing only.